perm filename FASLOA[NEW,LSP]2 blob
sn#388699 filedate 1978-10-14 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00032 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002
C00007 00003 FORMAT OF FASL FILES:
C00022 00004
C00023 00005
C00026 00006
C00032 00007
C00035 00008
C00039 00009
C00044 00010
C00047 00011
C00050 00012
C00053 00013
C00057 00014
C00063 00015
C00067 00016
C00070 00017
C00073 00018
C00076 00019
C00078 00020
C00080 00021
C00084 00022
C00087 00023
C00090 00024
C00093 00025
C00095 00026
C00097 00027
C00098 00028
C00100 00029
C00103 00030
C00105 00031
C00107 00032
C00111 ENDMK
C⊗;
;;; -*-MIDAS-*-
;;; **************************************************************
;;; ***** MACLISP ****** FASLOAD ********************************
;;; **************************************************************
;;; ** (C) COPYRIGHT 1978 MASSACHUSETTS INSTITUTE OF TECHNOLOGY **
;;; ****** THIS IS A READ-ONLY FILE! (ALL WRITES RESERVED) *******
;;; **************************************************************
PGBOT FSL
SUBTTL HAIRY RELOCATING LOADER (FASLOAD)
;;; BUFFER PARAMETERS
Q% 10% LLDBF==:100 ;LENGTH OF LOADER'S BINARY INPUT BUFFER ARRAY
Q% 10$ SA$ LLDBF==:1401
Q% 10$ SA% LLDBF==:1401
LLDAT==:770 ;LENGTH OF LOADER'S ATOMTABLE ARRAY
ILDAT==:1000 ;AMOUNT TO INCREMENT ATOMTABLE ARRAY
LLDSTB==:400 ;SIZE OF LDPUT'S SYMBOL TABLE ARRAY (IN 2-WD ENTRIES)
;;; PDL OFFSETS
IFE QIO,[
LDAGEN==:0 ;SAR FOR ATOMTABLE
LDBGEN==:-1 ;SAR FOR I/O BUFFER
LDPRLS==:-2 ;PURE CLOBBERING LIST
LDDDTP==:-3 ;DDT FLAG
] ;END OF IFE QIO
.ELSE,[
LDAGEN==:0 ;SAR FOR ATOMTABLE
LDPRLS==:-1 ;PURE CLOBBERING LIST
LDDDTP==:-2 ;DDT FLAG
LDBGEN==:-3 ;SAR FOR I/O BUFFER
] ;END OF .ELSE
LDNPDS==:4 ;NUMBER OF REGPDL SLOTS TAKE UP BY FASLOAD TEMPORARIES
;;; FASLOAD USES AN ARRAY OF ATOMS TO AVOID CONSTANTLY CREATING
;;; THE SAME ATOMS OVER AND OVER; IN PARTICULAR, THIS SAVES MUCH
;;; TIME IN INTERN FOR ATOMIC SYMBOLS. THIS TABLE IS CREATED
;;; INCREMENTALLY DURING THE LOAD FROM DATA IN THE FASL FILE. THE
;;; ARRAY HAS ONE ONE-WORD ENTRY FOR EACH ATOM. ENTRY 0 IS FOR NIL;
;;; THE OTHERS MAY BE IN ANY ORDER. THE FORMAT OF EACH ATOMTABLE
;;; ENTRY IS AS FOLLOWS:
;;; 4.9-4.1 IF NON-ZERO, THE THE LEFT HALF OF THE ENTRY
;;; (4.9-3.1) CONTAINS THE ADDRESS OF THE VALUE
;;; CELL OF THE ATOM (SYMBOLS ONLY). THIS WORKS
;;; BECAUSE ALL VALUE CELLS ARE ABOVE ADDRESS 777.
;;; NOTE THAT OTHER LEFT HALF BITS DESCRIBED HERE
;;; HAVE MEANING ONLY IF BITS 4.9-4.1 ARE ZERO.
;;; 3.4 THIS BIT IS TURNED ON IF THE ATOM IS PROTECTED
;;; FROM THE GARBAGE COLLECTOR BECAUSE IT IS POINTED
;;; BY SOME LIST STRUCTURE WHICH IS PROTECTED. THIS
;;; IS A HACK SO THAT USELESS ENTRIES WON'T BE MADE
;;; IN THE GC PROTECTION ARRAY (SEE GCPRO).
;;; 3.3-3.2 INDICATES THE TYPE OF ATOM: 0 => SYMBOL,
;;; 1 => FIXNUM, 2 => FLONUM, 3 => BIGNUM.
;;; 3.1 THIS BIT IS TURNED ON IF THE ATOM IS EVER
;;; REFERENCED, DIRECTLY OR INDIRECTLY, BY COMPILED
;;; CODE (IT MIGHT NOT BE IF USED ONLY IN MUNGABLES).
;;; IT INDICATES THAT THE ATOM MUST SOMEHOW BE
;;; PROTECTED FROM THE FEROCIOUS GARBAGE COLLECTOR.
;;; 2.9-1.1 CONTAINS THE ADDRESS OF THE ATOM. (SURPRISE!)
;;; NOTE THAT ONCE AN ATOM IS IN THE TABLE, THE FASL FILE WILL
;;; REFER TO THE ATOM BY ITS TABLE INDEX, SO THAT IT CAN BE
;;; RETRIEVED EXTREMELY QUICKLY.
;;; FORMAT OF FASL FILES:
;;;
;;; THE "NEW" FASLOAD SCHEME (AS OF 1/31/73) USES A NEW FORMAT FOR
;;; ITS FILES. A FASL FILE CONSISTS OF TWO HEADER WORDS, FOLLOWED BY
;;; A SERIES OF FASL BLOCKS; THE TWO HEADER WORDS ARE BOTH SIXBIT,
;;; THE FIRST BEING "*FASL+" (FOR HISTORICAL REASONS, "*FASL* IS
;;; ALSO ACCEPTED) AND THE SECOND THE CONTENTS OF LOCATION LDFNM2 IN
;;; THE LISP WHICH ASSEMBLED THE FILE (A VERSION NUMBER IN SIXBIT).
;;; EACH FASL BLOCK CONSISTS OF A WORD OF NINE FOUR-BIT RELOCATION
;;; BYTES, FOLLOWED BY NINE PIECES OF FASL DATA. THE LENGTH OF EACH
;;; DATA ITEM IS DEPENDENT ON THE RELOCATION TYPE; THUS FASLBLOCKS
;;; ARE OF VARYING LENGTH. THE LAST BLOCK MAY HAVE FEWER THAN NINE
;;; DATA ITEMS. THE RELOCATION TYPES AND THE FORMATS OF THE
;;; ASSOCIATED DATA ITEMS ARE AS FOLLOWS:
;;;
;;; TYPE 0 ABSOLUTE
;;; ONE ABSOLUTE WORD TO BE LOADED.
;;;
;;; TYPE 1 RELOCATABLE
;;; ONE WORD, THE RIGHT HALF OF WHICH IS RELOCATABLE; I.E. AT LOAD
;;; TIME THE LOAD OFFSET IS TO BE ADDED TO THE RIGHT HALF.
;;;
;;; TYPE 2 SPECIAL
;;; A WORD TO BE LOADED, WHOSE RIGHT HALF CONTAINS THE INDEX OF AN
;;; ATOM (HOPEFULLY OF TYPE PNAME) THE ADDRESS OF THE VALUE CELL OF
;;; WHICH IS TO REPLACE THE RIGHT HALF OF THE LOADED WORD. (IF NO
;;; VALUE CELL EXISTS, ONE IS TO BE CREATED.)
;;;
;;; TYPE 3 SMASHABLE CALL
;;; SIMILAR TO TYPE 4 (Q.V.) EXCEPT THAT THE INSTRUCTION IS ONE OF
;;; THE SERIES OF CALL UUOS WHICH MAY BE "SMASHED" FOR PURIFICATION
;;; PURPOSES. AT PRESENT THESE UUOS ARE: CALL, JCALL, NCALL, NJCALL.
;;;
;;; TYPE 4 QUOTED ATOM
;;; ONE WORD TO BE LOADED WHOSE RIGHT HALF CONTAINS THE INDEX OF AN
;;; ATOM WHOSE ADDRESS IS TO REPLACE THE RIGHT HALF OF THE WORD
;;; LOADED.
;;;
;;; TYPE 5 QUOTED LIST
;;; A SERIES OF WORDS REPRESENTING AN S-EXPRESSION TO BE CONSTRUCTED
;;; BY THE LOADER. THE FORMAT OF THESE WORDS IS BEST EXPLAINED BY
;;; THE ALGORITHM USED TO CONTRUCT THE S-EXPRESSION: THE LOADER
;;; EXAMINES BITS 4.7-4.9 OF SUCCESSIVELY READ WORDS, AND DISPATCHES
;;; ON THEM:
;;; 0 THE ATOM WHOSE INDEX IS IN THE RIGHT HALF OF THE WORD
;;; IS PUSHED ONTO A STACK.
;;; 1 THE LOADER POPS AS MANY ITEMS OFF THE STACK AS
;;; SPECIFIED BY THE NUMBER IN THE RIGHT HALF OF THE WORD
;;; AND MAKES A LIST OF THEM, SO THAT THE LAST ITEM POPPED
;;; BECOMES THE FIRST ITEM OF THE LIST; THIS LIST IS THEN
;;; PUSHED ONTO THE STACK.
;;; 2 THE LOADER POPS ONE ITEM OFF THE STACK AND PROCEEDS AS
;;; FOR 1, EXCEPT THAT THE ITEM FIRST POPPED IS USED TO
;;; END THE LIST INSTEAD IF NIL. (THIS ALLOWS FOR DOTTED
;;; PAIRS.)
;;; 3 THE TOP ITEM ON THE STACK IS EVALUATED AND STORED BACK
;;; ON THE TOP OF THE STACK.
;;; 4 THE RIGHT HALF OR THE WORD SPECIFIES THE LENGTH OF A
;;; HUNK TO BE MADE BY TAKING THAT MANY ITEMS FROM THE TOP
;;; OF THE STACK; THIS HUNK IS THEN PUSHED BACK.
;;; 5 UNUSED.
;;; 6 UNUSED.
;;; 7 THE LEFT HALF OF THE WORD SHOULD BE -1 OR -2,
;;; INDICATING THE SECOND LAST WORD OF THE DATA; IF -1,
;;; THE RIGHT HALF OF THIS WORD AND THE ADDRESS OF (WHAT
;;; SHOULD BE) THE SINGLE ITEM ON THE STACK (WHICH IS
;;; POPPED OFF) ARE MADE RESPECTIVELY INTO THE LEFT AND
;;; RIGHT HALVES OF A WORD TO BE LOADED INTO BINARY
;;; PROGRAM SPACE; IF -2, THE S-EXPRESSION IS PLACED INTO
;;; THE NEXT SLOT OF THE ATOMTABLE (SEE TYPE 12). THE ONE
;;; WORD REMAINING IS THE HASH KEY OF THE S-EXPRESSION AS
;;; COMPUTED BY SXHASH; THIS IS USED BY THE LOADER TO SAVE
;;; GCPRO SOME WORK.
;;;
;;; TYPE 6 GLOBALSYM
;;; ONE WORD; THE RIGHT HALF IS AN INDEX INTO THE TABLE LSYMS IN
;;; LISP. THE INDICATED VALUE IS RETRIEVED, NEGATED IF BIT 4.9 OF
;;; THE DATA WORD IS 1, AND ADDED TO THE RIGHT HALF OF THE LAST
;;; WORD LOADED INTO BINARY PROGRAM SPACE. THIS ALLOWS LAP CODE
;;; TO REFER TO SELECTED LOCATIONS INTERNAL TO LISP WITHOUT
;;; GETTING SYMBOLS FROM DDT.
;;;
;;; TYPE 7 GETDDTSYM
;;; IF THE FIRST WORD IS -1, THEN THE LOAD OFFSET IF ADDED INTO
;;; THE LEFT HALF OF THE WORD MOST RECENTLY LOADED INTO BINARY
;;; PROGRAM SPACE (THIS IS HOW LEFT HALF RELOCATION IS
;;; ACCOMPLISHED). OTHERWISE, THE FIRST WORD CONTAINS IN BITS
;;; 1.1-4.5 A SYMBOL IN SQUOZE CODE. THE LOADER GETS THE VALUE OF
;;; THIS SYMBOL FROM DDT IF POSSIBLE, NEGATES IT IF BIT 4.9 IS 1,
;;; THEN ADDS THE RESULT TO THE FIELD OF THE LAST WORD LOADED AS
;;; SPECIFIED BY BITS 4.6-4.7:
;;; 3 = ENTIRE WORD
;;; 2 = AC FIELD ONLY
;;; 1 = RIGHT HALF ONLY
;;; 0 = ENTIRE WORD, BUT SWAP HALVES OF VALUE BEFORE ADDING.
;;; THESE FOUR FIELDS CORRESPOND TO OPCODE, AC, ADDRESS, AND INDEX
;;; FIELDS RESPECTIVELY IN A LAP INSTRUCTION. IF BIT 4.8 IS A 1,
;;; THEN ANOTHER WORD FOLLOWS, CONTAINING THE VALUE OF THE SYMBOL
;;; AS OBTAINED FROM DDT AT ASSEMBLE TIME. IF THE VERSION NUMBER
;;; OF THAT LISP (AS DETERMINED FROM THE SECOND FILE HEADER WORD)
;;; IS THE SAME AS THAT OF THE LISP BEING LOADED INTO, THEN THIS
;;; VALUE IS USED AND DDT IS NOT CONSULTED AT LOAD TIME; THIS IS
;;; FOR SPEED. IF THE VERSION NUMBERS ARE DIFFERENT, THEN DDT IS
;;; CONSULTED.
;;;
;;; TYPE 10 ARRAY REFERENCE
;;; ONE WORD TO BE LOADED, WHOSE RIGHT HALF CONTAINS THE ATOMINDEX
;;; OF AN ATOMIC SYMBOL. IF THE SYMBOL HAS AN ARRAY PROPERTY, IT
;;; IS FETCHED; OTHERWISE ONE IS CREATED. THE RIGHT HALF OF THE
;;; WORD TO BE LOADED IS REPLACED WITH THE ADDRESS OF THE SECOND
;;; WORD OF THE ARRAY POINTER (I.E. OF THE TTSAR). IN THIS WAY
;;; ACCESSES TO ARRAYS CAN BE OPEN-CODED.
;;;
;;; TYPE 11 UNUSED
;;;
;;; TYPE 12 ATOMTABLE INFO
;;; A HEADER WORD, POSSIBLY FOLLOWED BY OTHERS, DEPENDING ON BITS
;;; 4.7-4.9:
;;; 0 THE RIGHT HALF IS THE NUMBER OF WORDS FOLLOWING, WHICH
;;; CONSTITUTE THE PNAME OF A PNAME-TYPE ATOM, IN THE
;;; ORDER OF THEIR APPEARANCE ON A PROPERTY LIST. THE ATOM
;;; IS INTERNED.
;;; 1 THE ONE WORD FOLLOWING IS THE VALUE OF A FIXNUM TO BE
;;; CREATED.
;;; 2 THE FOLLOWING WORD IS THE VALUE OF A FLONUM.
;;; 3 THE RIGHT HALF IS THE NUMBER OF FIXNUM COMPONENTS OF A
;;; BIGNUM FOLLOWING, MOST SIGNIFICANT WORD FIRST. BIT 3.1
;;; IS THE SIGN OF THE BIGNUM.
;;; 4 THE FOLLOWING TWO WORDS ARE A DOUBLE-PRECISION NUMBER.
;;; 5 THE FOLLOWING TWO WORDS ARE A COMPLEX NUMBER.
;;; 6 THE FOLLOWING FOUR WORDS ARE A DUPLEX NUMBER.
;;; 7 UNUSED.
;;; THE ATOM THUS CREATED IS ASSIGNED A PLACE IN THE ATOMTABLE
;;; MAINTAINED BY THE LOADER (AS AN ARRAY) USING CONSECUTIVE
;;; LOCATIONS; FROM THAT POINT ON OTHER DATA ITEMS REFERRING TO
;;; THAT ITEM CAN DO SO BY THE INDEX OF THE ATOM IN THIS TABLE.
;;; SEE ALSO TYPES 5 AND 16, WHICH ALSO MAKE ENTRIES IN THE
;;; ATOMTABLE.
;;;
;;; TYPE 13 ENTRY INFO
;;; TWO WORDS. THE LEFT HALF OF THE FIRST WORD IS THE ATOMINDEX
;;; OF THE NAME OF THE FUNCTION BEING DEFINED; THE RIGHT HALF
;;; THAT OF THE SUBR TYPE (THE PROPERTY UNDER WHICH TO CREATE THE
;;; ENTRY POINT, E.G. SUBR OR FSUBR). THE RIGHT HALF OF THE
;;; SECOND WORD IS THE LOCATION OF THE ENTRY POINT AS A
;;; RELOCATABLE POINTER: THE LOAD OFFSET MUST BE ADDED TO IT. THE
;;; LEFT HALF OF THE SECOND WORD CONTAINS THE ARGS PROPERTY, IN
;;; INTERNAL ARGS PROPERTY FORMAT, AS SPECIFIED IN THE ORIGINAL
;;; LAP CODE BY THE ARGS CONSTRUCT.
;;;
;;; TYPE 14 LOC
;;; THE WORD IS A RELOCATABLE QUANTITY SPECIFYING WHERE TO
;;; CONTINUE LOADING. IT IS NOT PERMITTED TO LOC BELOW THE
;;; ORIGIN OF THE ASSEMBLY. IF THE LOC IS TO A LOCATION HIGHER
;;; THAN ANY YET LOADED INTO, THEN FASLOAD ZEROS OUT ALL WORDS
;;; ABOVE THAT HIGHEST LOCATION UP TO THE LOCATION SPECIFIED.
;;; FASLOAD KEEPS TRACK OF THE HIGHEST LOCATION EVER LOADED INTO;
;;; THIS VALUE PLUS ONE BECOMES THE VALUE OF BPORG AT THE END OF
;;; ASSEMBLY, REGARDLESS OF THE STATE OF THE LOCATION POINTER
;;; WHEN LOADING TERMINATES. THIS TYPE IS NEVER USED BY LAP
;;; CODE, BUT ONLY BY MIDAS .FASL CODE.
;;;
;;; TYPE 15 PUTDDTSYM
;;; FIRST WORD, THE SYMBOL IN SQUOZE CODE. IF BIT 4.9=0, THE
;;; SYMBOL IS DEFINED TO DDT IF POSSIBLE WITH THE ADDRESS OF THE
;;; WORD OF BINARY PROGRAM SPACE ABOUT TO BE LOADED INTO AS ITS
;;; VALUE. IF BIT 4.9=1, THE VALUE IS GOBBLED FROM THE FOLLOWING
;;; WORD. BIT 4.8 (OF THE WORD CONTAINING THE SQUOZE) MEANS
;;; RELOCATE THE LEFT HALF OF THE VALUE BY THE LOAD OFFSET, AND
;;; BIT 4.7 LIKEWISE FOR THE RIGHT HALF. WHETHER OR NOT THE
;;; SYMBOL ACTUALLY GETS PUT IN DDT'S SYMBOL TABLE IS A FUNCTION
;;; OF THREE CONDITIONS: FIRST, THAT THERE IS A DDT WITH A SYMBOL
;;; TABLE; SECOND, THE VALUE OF THE LISP VARIABLE "SYMBOLS";
;;; THIRD, BIT 4.6 OF THE FIRST PUTDDTSYM WORD. THE FIRST
;;; CONDITION OF COURSE MUST BE SATISFIED. IF SO, THEN THE SYMBOL
;;; IS PUT IN THE SYMBOL TABLE ONLY IF SYMBOLS HAS A NON-NIL
;;; VALUE. FURTHERMORE, IF THAT VALUE IS THE ATOM SYMBOLS ITSELF,
;;; THEN THE SYMBOL IS PUT ONLY IF BIT 4.6 IS ON (INDICATING A
;;; "GLOBAL" SYMBOL).
;;;
;;; TYPE 16 EVAL MUNGEABLE
;;; A SERIES OF WORDS SIMILAR TO THOSE FOR TYPE 5, BUT WITH NO
;;; FOLLOWING HASH KEY. AN S-EXPRESSION IS CONSTRUCTED AND
;;; EVALUATED. THIS IS USED FOR THE SO-CALLED "MUNGEABLES" IN A
;;; FILE OF LAP CODE. IF THE LEFT HALF OF THE LAST WORD IS -1,
;;; THE VALUE IS THROWN AWAY. IF IT IS -2, THE VALUE IS ENTERED
;;; IN THE ATOMTABLE.
;;;
;;; TYPE 17 END OF BINARY
;;; ONE WORD, WHICH MUST BE "*FASL+" (OR "*FASL*") IN SIXBIT.
;;; THIS SHOULD BE THE LAST DATA WORD IN THE FILE. ANY RELOCATION
;;; BYTES LEFT OVER AFTER A TYPE 17 ARE IGNORED. THIS SHOULD BE
;;; FOLLOWED EITHER BY END OF FILE OR A WORD FULL OF ↑C'S.
;;; INTERNAL AUTOLOAD ROUTINE
IFE QIO,[
IALB: HRRZ C,(A)
HLRZ A,IRACOM
HRRZ B,@IUNIT
PUSHJ P,CONS
JSP T,SPECBIND
0 A,IUNIT
NW% SAVEFX UFN1 UFN2
MOVEI A,(C) ;INTERNAL AUTOLOAD BREAK IS ESSENTIALLY FASLOAD
PUSHJ P,FASLOAD
NW% RSTRFX UFN2 UFN1
JRST UNBIND
] ;END OF IFE QIO
IFN QIO,[
IALB: HRRZ AR2A,VDEFAULTF ;SUBR 1
JSP T,SPECBIND
0 AR2A,VDEFAULTF
HRRZ A,(A)
IT$ MOVEI B,QCOMDIR
IT% MOVEI B,QCOMDEV
PUSHJ P,MERGEF
PUSHJ P,LOAD
JRST UNBIND
] ;END OF IFN QIO
FASLOAD:
JSP TT,FWNACK
FA01234,,QFASLOAD
SKIPE FASLP
JRST LDALREADY
PUSH P,FLP ;FOR DEBUGGING PURPOSES
PUSH P,FXP .SEE LDEOMM
PUSH P,SP
10$ SETOM LDEOFP ;FLAG FOR CRUFTY D10 DUMP MODE I/O EOF
IFE QIO,[
AOJN T,LDXXX7
HLRZ A,(A)
MOVEI B,QFASLL
PUSHJ P,CONS
LDXXX7: MOVEM A,LDFNAM
] ;END OF IFE QIO
IFN QIO,[
SA$ SETOM SAFSFG
PUSHJ P,FIL6BT
SA$ SETZM SAFSFG
MOVSI T,(SIXBIT \*\)
IT$ MOVE TT,[SIXBIT \FASL\] ;DEFAULT SECOND FILE NAME IS "FASL"
10$ MOVSI TT,(SIXBIT \FAS\) ;DEFAULT FILE NAME EXTENSION IS "FAS"
20$ MOVE TT,[ASCII \FASL\]
20% CAMN T,(FXP)
20% MOVEM TT,(FXP)
20$ SKIPE -L.6VRS-L.6EXT+1(FXP) ;EXTENSION NULL?
20$ CAMN T,-L.6VRS-L.6EXT+1(FXP) ;OR EQUAL TO *?
20$ MOVEM TT,-L.6VRS-L.6EXT+1(FXP) ;EITHER, USE FASL
PUSHJ P,DMRGF
PUSHJ P,6BTNML
] ;END OF IFN QIO
MOVEI B,TRUTH
JSP T,SPECBIND
Q$ 0 A,LDFNAM ;QIO MUST BIND LDFNAM FOR POSSIBLE RECURSIVE FASLOAD
0 B,VNORET
Q% 0 B,FASLP
Q$ FASLP
IFE QIO,[
PUSH P,IUNIT
MOVEI T,6 ;OPEN FASL FILE IN BLOCK IMAGE MODE
PUSHJ P,UINITA
10% .OPEN DSIC,UTIN
10% JRST LDOERR
IFN D10,[
MOVEI T,16
SETZ T+2,
PUSHJ P,LDOPN1 ;USE COMMON OPEN
JRST LDOERR ;USE LOAD ERROR MESSAGE
LOOKUP DSIC,T
JRST LDOERR ;SAME MESSAGE
SETZM D10PTR
] ;END OF IFN D10
SUB P,R70+1 ;SUB OFF OLD IUNIT
UNLOCKI
PUSHJ P,LDFNSET
MOVEM A,LDFNAM
] ;END OF IFE QIO
IFN QIO,[
PUSH P,[LDXXY1]
PUSH P,A
PUSH P,[QFIXNUM]
MOVNI T,2
JRST $OPEN
LDXXY1: MOVEM A,FASLP
PUSH P,A
HRRZM A,LDBSAR
MOVE A,LDFNAM
PUSHJ P,DEFAULTF
SETZM LDTEMP ;CROCK!
] ;END OF IFN QIO
;FALLS THROUGH
;FALLS IN
;;; COME HERE TO "DO IT SOME MORE"
LDDISM: PUSHJ P,LDGDDT ;SET UP DDT FLAG: 0 => NO DDT;
PUSH P,TT ;-1,,0 => DDT, NO SYMBOLS; 1,,X => DDT, SYMBOLS
;X MAY BE 0, OR SAR FOR SYMBOL TABLE ARRAY
; (SEE LDPUT)
SKIPN F,VPURE ;SET UP CALL PURIFY FLAGS:
;400000,,XXX => NO PURIFY HACKERY
TLOA F,400000 ;200000,,XXX => SUBST XCTS FOR CALLS,
; PUT CALLS IN SEPARATE PAGES
;100000 BIT MEANS FASLOAD INTO HISEG (D10 ONLY)
HRRZ F,VPURCLOBRL ;0,,<PURE LIST> => SUBST PUSHJS AND
; JRSTS FOR CALLS
PUSH P,F ; ANY CALLS NOT IMMEDIATELY SMASHABLE
MOVE A,VPURE ; ARE CONSED ONTO THE PURE LIST
PUSHJ P,FIXP ;LEAVES VALUE IN TT IF INDEED FIXNUM
JUMPE A,LDXXX1
MOVSI F,200000
IORM F,(P)
IFN D10,[
JUMPGE TT,LDXQQ7 ;IF PURE IS A NEGATIVE FIXNUM, DO HISEG HACKERY
SA% HRROI T,.GTSGN ;FIND WHETHER HISEG SHARABLE (FROM
SA% GETTAB T, ;6.03 MONITOR CALLS)
SA% .VALUE
SA% TLNN T,(SN%SHR)
SA$ SKIPL .JBHRL ;IS HISEG CURRENTLY WRITE-PROTECTED?
JRST LDXQQ5
PUSH FXP,TT
LOCKI ;LOCK OUT INTS AROUND USE OF TMPC
SKIPN SGANAM
JRST FASLUH
MOVEI T,.IODMP
MOVE TT,SGADEV
SETZ D,
OPEN TMPC,T ;OPEN UP .SHR FILE DEVICE IN DUMP MODE
JRST FASLUH
MOVE T,SGANAM
MOVE TT,SGAEXT
SETZ D,
MOVE R,SGAPPN
LOOKUP TMPC,T
JRST FASLUR
SA$ MOVS T,R
SA% JUMPGE R,FASLUR
SA% HLRE T,R
MOVNS T ;T GETS LENGTH OF .SHR FILE
PUSHJ P,LDRIHS ;GO READ IN HIGH SEGMENT (FROM WITHIN LOSEG!)
LDRTHS: RELEASE TMPC, ;FLUSH TEMP CHANNEL
UNLOCKI
POP FXP,TT
MOVE F,SVPRLK ;CAN NOW USE SAVED PURE SEGMENTS FROM LAST TIME
SETZM SVPRLK
MOVEM F,PRSGLK
LDXQQ5: MOVSI F,100000
IORM F,(P) ;SET FLAG SAYING WE'RE HACKING THE HISEG
MOVMS TT
PUSHJ P,LDXHHK ;SET UP XCT PAGES USING HISEG
MOVE A,V.PURE
PUSHJ P,FIXP ;LEAVES VALUE IN TT IN INDEED FIXNUM
JUMPE A,LDXXX1 ;IF FIXNUM, IT IS AN ESTIMATE OF PURE FREE STG
CAIG TT,10 ;IF 10 OR LESS, MULTIPLY BY 1024.
LSH TT,12
CAILE TT,0 ;CHECK FOR REASONABLENESS
CAILE TT,MEMORY+.RL1-ENDHI
JRST LDYERR
MOVSI D,-NFF-1
SUB TT,PFSSIZ(D) ;SUBTRACT FROM ESTIMATE THE CURRENT
AOBJN D,.-1 ; SIZES OF EXISTING PURE AREAS
MOVE D,PRSGLK
LDXQQ2: JUMPE D,LDXQQ3 ;ALSO ACCOUNT FOR ANY PURE SEGMENTS
SUBI TT,SEGSIZ ; ALREADY IN THE FREELIST
LDB D,[SEGBYT,,GCST(D)]
JRST LDXQQ2
LDXQQ3: JUMPLE TT,LDXXX1 ;JUMP IF GUESSTIMATE ALREADY SATISFIED
ADDI TT,SEGSIZ-1 ;ROUND UP TO AN INTEGRAL
ANDI TT,SEGMSK ; NUMBER OF SEGMENTS
MOVE D,HBPORG
ADDI D,SEGSIZ-1 ;ALSO ROUND UP HISEG BPORG
ANDI D,SEGMSK
MOVE R,D
ADD D,TT
SUBI D,1
TLNE D,-1 ;COMPLAIN IF NOT ENOUGH MEMORY
JRST FASLNX
MOVEM D,HBPORG ;UPDATE HISEG BPORG PAST ALLOCATED SEGMENTS
AOS HBPORG
CAMG D,HBPEND
JRST LDXQQ6
MOVEM D,HBPEND ;IF NEW HISEG BPORG TOO LARGE,
SA% HRLZI D,(D)
SA% CORE D,
SA$ CORE2 D, ; MUST REQUEST MORE CORE FOR HISEG
HALT
LDXQQ6: LSH R,-SEGLOG ;UPDATE SEGMENT TABLES,
LSH TT,-SEGLOG ; AND ADD PURE SEGMENTS TO FREELIST
MOVE D,[$XM+PUR,,QRANDOM]
MOVE F,PRSGLK
LDXQQ8: MOVEM D,ST(R)
SETZM GCST(R)
DPB F,[SEGBYT,,GCST(R)]
MOVEI F,(R)
ADDI R,1
SOJG TT,LDXQQ8
MOVEM F,PRSGLK
JRST LDXXX1
LDXQQ7: PUSHJ P,LDXHAK ;SET UP XCT HACK PAGES WITHOUT HISEG
] ;END OF IFN D10
;FALLS THROUGH
;FALLS IN
LDXXX1:
IFE QIO,[
HRRZ B,FASLP ;FASLP IS T FIRST TIME, ELSE
CAIE B,TRUTH ; SAR OF I/O BUFFER ARRAY
JRST LDXXX8
SETZM LDTEMP
MOVEI TT,LLDBF ;CREATE I/O BUFFER ARRAY
MOVSI A,400000
PUSHJ P,MKFXAR
HRRZM B,LDBSAR ;SAVE ADDRESS OF SAR
MOVEM B,FASLP
LDXXX8: PUSH P,B ;SAVE SAR FOR I/O BUFFER [FROM GC]
] ;END OF IFE QIO
MOVE TT,[-LLDAT+1,,1] ;INIT ATOMTABLE AOBJN INDEX
MOVEM TT,LDAAOB
MOVEI TT,LLDAT ;CREATE ATOMTABLE ARRAY
MOVSI A,400000
PUSHJ P,MKLSAR
PUSH P,A ;SAVE SAR OF ATOM-TABLE ARRAY FOR GC PROTECTION
HRRZM B,LDASAR ;SAVE ADDRESS OF SAR
PUSHJ P,LDLRSP ;LOCKI, AND SET UP ARRAY POINTERS
SETZ TT, ;ENTRY 0 IN ATOMTABLE IS FOR NIL
SETZM @LDAPTR
MOVEI TT,LDFERR ;INIT ADDRESS FOR PREMATURE EOF
MOVEM TT,LDEOFJ
SKIPE F,LDTEMP ;IF LDTEMP IS NON-NIL, IT IS THE SAVED I/O BUFFER POINTER
JRST LDXXX9
JSP T,LDGTW1 ;GET FIRST WORD OF FILE
TRZ TT,1 ;COMPATIBILITY CROCK
CAME TT,[SIXBIT \*FASL*\] ;IT BETTER BE THIS VALUE!
JSP D,LDFERR
LDXXX9: JSP T,LDGTWD ;GET VERSION OF LISP FILE WAS ASSEMBLED IN
XOR TT,LDFNM2
MOVEM TT,LDF2DP ;NON-ZERO IFF VERSIONS DIFFERENT
MOVE AR1,[000400,,LDBYTS] ;INIT RELOCATION BYTES POINTER
SETZM LDHLOC
HRRZ R,@VBPORG
10$ MOVE TT,LDPRLS(P)
10$ TLNE TT,100000 ;SKIP UNLESS LOADING INTO HISEG
10$ HRRZ R,HBPORG
HRRM R,LDOFST ;INITIALIZE LOAD OFFSET
JRST LDABS0 ;R HAS ADDRESS TO LOAD NEXT WORD INTO
SUBTTL ROUTINE TO SET UP PAGES FOR XCT HACK (D10, FIXED NUMBER OF SLOTS)
IFN D10,[
;;; TT HAS NUMBER OF WORDS (1K BLOCKS IF <8) DESIRED.
LDXHHK: HRROS (P) ;THIS ENTRY USES THE HISEG
LDXHAK: SKIPE LDXSIZ ;MAYBE WE NEED TO SET UP PAGES FOR XCT HACKERY
POPJ P, ;IF NOT, JUST EXIT
JUMPLE TT,LDXERR
CAIG TT,10 ;IF 10 OR LESS, MULTIPLY BY 1024.
LSH TT,12
ADDI TT,PAGSIZ-1 ;ROUND UP TO A WHOLE NUMBER OF PAGES
ANDI TT,PAGMSK
TLNE TT,-1
JRST LDXERR
PUSH FXP,TT
MOVE D,(FXP) ;GET ESTIMATED NUMBER OF LINKS
MOVEM D,LDXSIZ ;SAVE AS SIZE OF XCT AREA
MOVEM D,LDXSM1 ;ALSO NEED THAT VALUE MINUS 1
SOS LDXSM1
MOVE TT,@VBPORG ;CREATE TWO AREAS IN BPS THAT BIG:
HRRZ T,TT ; THE FIRST FOR THE XCTS TO POINT TO,
ADD TT,D ; THE SECOND TO RESTORE THE FIRST FROM
HRL T,TT
MOVE R,(P)
TLNE R,1
HRL T,HBPORG
MOVEM T,LDXBLT ;SAVE BLT POINTER FOR RESTORING
TLNN R,1 ;USING HISEG, DON'T TAKE SECOND AREA FROM LOSEG
ADD TT,D ;ADD IN FOR SECOND AREA
JSP T,FXCONS ;NEW VALUE FOR BPORG
PUSH P,A
TLNN R,1
LSH D,1
MOVE TT,D
PUSHJ P,LGTSPC ;NOW TRY TO GET REQUIRED CORE
JUMPE TT,FASLNX
MOVE R,-1(P)
TLNN R,1
JRST LDXHK3
MOVE D,(FXP) ;GOBBLE SECOND AREA OUT OF HISEG
ADD D,HBPORG
TLNN D,-1
JRST LDXHK2
LDXHK1: SETZM LDXSIZ ;HAVEN'T REALLY WON AFTER ALL
JRST FASLNX
LDXHK2: MOVEM D,HBPORG
SUBI D,1
CAMG D,HBPEND ;MAY NEED TO EXTEND HISEG
JRST LDXHK3
MOVEM D,HBPEND
SA% HRLZI D,(D)
SA% CORE D,
SA$ CORE2 D,
JRST LDXHK1
LDXHK3: POP P,VBPORG ;GIVE BPORG NEW VALUE
MOVE T,LDXBLT ;ZERO OUT BOTH AREAS
MOVE TT,@VBPORG
HRL T,T
SETZM (T)
ADDI T,1
BLT T,-1(TT)
TLNN R,1
JRST LDXHK5
MOVS T,LDXBLT ;WHEN USING HISEG, NEED AN EXTRA
MOVE TT,HBPORG ; BLT TO ZERO OUT SECOND AREA
BLT T,-1(TT)
LDXHK5: HRRZ T,LDXBLT ;SET UP LDXDIF WITH THE DIFFERENCE
HLRZ TT,LDXBLT ; BETWEEN THE ORIGINS OF AREA 1 AND
SUB T,TT .SEE LDPRC6
HRRM T,LDXDIF ; AREA 2 TO MAKE INSTALLING ENTRIES EASIER
POPI FXP,1
JRST TRUE
] ;END IFN D10
SUBTTL ITS AND TOPS-20, VARIABLE NUMBER OF XCT PAGES, DYNAMICALLY ALLOCATED
IFN ITS+D20,[
LDXHAK: PUSH FXP,AR1 ;AR1 MUST BE PRESERVED, AT ALL COSTS!
LOCKI ;INTERRUPTS MUST BE OFF OVER CALL TO GRBSEG
PUSHJ P,GRBSEG ;GET ONE SEGMENT OF TYPE RANDOM
JRST LDXIRL ;RELEASE INTERRUPTS AND GIVE NON-SKIP RETURN
UNLOCKI
PUSHJ P,GRBPSG ;GET ONE PURE SEGMENT INTO AC T
POP FXP,AR1
LSH T,SEGLOG ;MAKE PURE SEGMENT INTO ADDRESS
HRRZM T,LDXPSP(TT) ;REMEMBER PURE SEGMENT ADDRESS
HRLI T,(T) ;BUILD A BLT POINTER TO ZERO PURE PAGE
HRRZI D,SEGSIZ-1(T) ;LAST LOC TO ZERO
SETZM (T) ;ZERO FIRST LOC
ADDI T,1
BLT T,(D) ;AND ALL THE REST
HRLZI T,LDXOFS(TT) ;BUILD BLT POINTER TO CLEAR NEW IMPURE SEG
HRRI T,LDXOFS+1(TT)
SETZM LDXOFS(TT)
BLT T,SEGSIZ-1(TT) ;CLEAR THE WHOLE SEGMENT
MOVNI T,LDHSH1+1 ;NUMBER OF ENTRIES IN TABLE
IMULI T,LDX%FU ;MAKE INTO NEGATIVE PERCENTAGE
PUSH FXP,TT
IDIVI T,100.
POP FXP,TT
MOVEM T,LDXLPC ;AND THE COUNT
MOVE T,LDXLPL ;REMEMBER LOC OF LAST PAGE USED
MOVEM TT,LDXLPL ;SAVE THIS PAGE LOCATION
JUMPE T,LDXFLC ;STORE IN POINTER LOC IF NO PREVIOUS SEGMENTS
HRLM TT,(T) ;LINK INTO LIST
AOS (P)
POPJ P,
LDXFLC: MOVEM TT,LDXPNT
AOS (P)
POPJ P,
LDXIRL: UNLOCKI
POP FXP,AR1
POPJ P,
] ;END IFN ITS+D20
SUBTTL MAIN FASLOAD LOOP
;;; FROM THIS POINT ON, UNTIL A FATAL ERROR OCCURS OR LOCATION LDFEND IS REACHED,
;;; THESE ACCUMULATORS ARE DEDICATED TO THE FOLLOWING PURPOSES:
;;; AR1 BYTE POINTER FOR GETTING SUCCESSIVE RELOCATION TYPES
;;; R AOBJN POINTER FOR PUTTING WORDS INTO BINARY PROGRAM SPACE
;;; F AOBJN INDEX FOR ACCESSING WORDS FROM INPUT BUFFER ARRAY
LDREL: HRRI TT,@LDOFST ;[RELOCATABLE WORD]
LDABS: MOVEM TT,(R) ;[ABSOLUTE WORD]
LDABS1: AOBJN R,LDBIN ;JUMP IF ROOM LEFT OF WHAT WE GRABBED
LDABS0:
10$ MOVE TT,LDPRLS(P) ;FOR D10, MUST PASS LDPRLS IN TT TO LDGTSP
PUSHJ P,LDGTSP
PUSHJ P,LDRSPT
LDBIN: SKIPE INTFLG ;[LOAD BINARY WORD (OR SOME OTHER MESS)]
PUSHJ P,LDTRYI ;GIVE A POOR INTERRUPT A CHANCE IN LIFE
TLNN AR1,770000
JRST LDBIN2 ;OUT OF RELOCATION BYTES - MUST GET MORE
LDBIN1: JSP T,LDGTWD ;GET WORD FROM INPUT FILE
ILDB T,AR1 ;GET CORRESPONDING RELOCATION BYTE
JSP D,@LDTTBL(T) ; - IT TELLS US WHERE TO GO
LDBIN2: JSP T,LDGTWD ;GET WORD OF RELOCATION BYTES
MOVEM TT,LDBYTS
SOJA AR1,LDBIN1 ;INIT BYTE POINTER AND GO GET DATA WORD
LDTTBL: LDABS ; 0 ABSOLUTE
LDREL ; 1 RELOCATABLE
LDSPC ; 2 SPECIAL
LDPRC ; 3 PURIFIABLE CALL
LDQAT ; 4 QUOTED ATOM
LDQLS ; 5 QUOTED LIST
LDGLB ; 6 GLOBALSYM PATCH
LDGET ; 7 GET DDT SYMBOL PATCH
LDAREF ; 10 ARRAY REFERENCE
LDFERR ; 11 UNUSED
LDATM ; 12 ATOMTABLE ENTRY
LDENT ; 13 ENTRY POINT INFO
LDLOC ; 14 LOC TO ANOTHER PLACE
LDPUT ; 15 PUT DDT SYMBOL
LDEVAL ; 16 EVALUATE MUNGEABLE
LDBEND ; 17 END OF BINARY
;;; LOADER GET SPACE ROUTINE. PUTS SOME DISTANCE BETWEEN BPORG AND BPEND.
;;; R MUST BE SET UP ALREADY. FOR D10, TT MUST HAVE LDPRLS.
;;; THE LEFT HALF OF R IS ADJECTED TO REFLECT THE SPACE OBTAINED.
LDGTSP:
10$ TLNE TT,100000 ;CHECK IF LOADING INTO HISEG
10$ JRST LDGSP3 ;IF SO, EXPAND THAT
MOVE TT,@VBPEND ;SEE IF ENOUGH ROOM LEFT TO GRAB MORE
SUB TT,@VBPORG
SUBI TT,100 ;RANDOMLY CHOSEN QUANTITY
JUMPGE TT,LDGSP1 ;YES - GO GRAB IT
SAVEFX AR1 D R F
MOVEI TT,4*PAGSIZ ;GET MANY BLOCKS OF BPS
LDGS0A: MOVEM TT,GAMNT
PUSHJ P,GTSPC1
JUMPN TT,LDGS0H
MOVE TT,GAMNT
CAIG TT,100
JRST FASLNC
MOVEI TT,100
JRST LDGS0A
LDGS0H: RSTRFX F R D AR1
LDGSP1: MOVEI TT,(R)
ADDI TT,PAGSIZ ;TRY TO GOBBLE <PAGSIZ>
CAMLE TT,@VBPEND ; WORDS, BUT IN ANY CASE
MOVE TT,@VBPEND ; NO MORE THAN BEYOND BPEND
JSP T,FIX1A
MOVEM A,VBPORG
MOVEI TT,(R)
SUB TT,@VBPORG
HRLI R,(TT) ;INIT AOBJN POINTER IN R
POPJ P,
IFN D10,[
LDGSP3: MOVE TT,HBPEND
SUBI TT,(R) ;DO NOT MERGE THIS WITH FOLLOWING SUBI! MAYBE R>777700
SUBI TT,100 ;RANDOMLY CHOSEN QUANTITY
JUMPGE TT,LDGSP6
MOVE TT,HBPEND
ADDI TT,4*PAGSIZ
TLNE TT,-1
MOVSI TT,(MEMORY)
ADDI TT,PAGSIZ-1
ANDCMI TT,#PAGMSK ;*NOT* SAME AS ANDI TT,PAGMSK !!!
MOVE T,TT
SUBI T,1
CAMG T,HBPEND
JRST LDGSP4
SA% HRLZI T,(T)
SA% CORE T,
SA$ CORE2 T,
JRST FASLNC
MOVE AR2A,[$XM+PUR,,QRANDOM]
AOS B,HBPEND
MOVEI C,(B)
SUBI C,(TT)
LSHC B,-SEGLOG
HRLI B,(C)
LDGSP5: MOVEM AR2A,ST(B)
SETZM GCST(B)
AOBJN B,LDGSP5
LDGSP4: MOVEM TT,HBPEND
SOS HBPEND
LDGSP6: MOVE TT,HBPEND
MOVEM TT,HBPORG
SUBM R,TT
HRLI R,(TT)
POPJ P,
] ;END OF IFN D10
SUBTTL SPECIAL VALUE CELL AND QUOTED ATOM REFERENCES
LDSPC: MOVE T,TT ;[SPECIAL]
HLR TT,@LDAPTR ;GET ADDRESS OF SPECIAL CELL
TRNE TT,777000 ;WAS SUCH AN ADDRESS REALLY THERE?
JRST LDABS ;YES, WIN
TRNE TT,6 ;NO, IS THIS ATOM A NUMBER
JSP D,LDFERR ;YES - LOSE!!!
HRRZ TT,T ;IS THERE AN ATOM THERE AT ALL
HRRZ A,@LDAPTR
SKIPN D,A
JSP D,LDFERR ;NO, LOSE
HLRZ B,(A)
HRRZ A,(B)
CAIE A,SUNBOUND
JRST LDSPC1
PUSH P,D ;NONE THERE - MUST MAKE ONE
MOVEI B,QUNBOUND
JSP TT,MAKVC ;RETURN SY2 POINTER IN B
LDSPC1: HLRZ TT,(B) ;GET SYMBOL FLAG BITS
TRO TT,SY.CCN\SY.OTC ;NEEDED-BY-COMPILED-CODE, OTHER THAN CALL
TRNN TT,SY.PUR ;WAS VALUE CELL PURE?
HRLM TT,(B) ;NO, THEN MUST PROTECT VALUE CELL
MOVE TT,T ;SAVE ADDRESS OF VALUE CELL
HRLM A,@LDAPTR ; IN ATOMTABLE
HRR TT,A ;AT LAST WE WIN
JRST LDABS
LDQAT: MOVE D,@LDAPTR ;[QUOTED ATOM]
TLNN D,777001 ;SKIP IF SPECIAL OR ALREADY USED
TLO D,1 ;ELSE TURN ON REFERENCE BIT
MOVEM D,@LDAPTR
HRRI TT,(D)
TRNN D,-1
JRST LDABS ;DON'T HACK ANYTHING FOR NIL
TLNE D,777006 ;IF NUMBER OR ALREADY HACKED SYM BLK, SKIP IT
JRST LDABS
HLRZ T,(D)
HLL T,(T) ;FETCH SYMBOL BITS
TLO T,SY.CCN\SY.OTC ;FLAG SYMBOL AS NEEDED FOR OTHER THAN CALL
TLNN T,SY.PUR ;DON'T TRY TO WRITE IF PURE
HLLM T,(T)
JRST LDABS
SUBTTL QUOTED LIST REFERENCES
LDQLS: MOVSI D,11 ;[QUOTED LIST]
SKIPL LDPRLS(P) ;CAN'T COUNT ON ANYTHING IN PURE
MOVSI D,1 ; FREE STORAGE PROTECTING ANYTHING
PUSHJ P,LDLIST ;GOBBLE UP A LIST
MOVEM TT,(R) ;PUT WORD IN BPS
JSP T,LDGTWD ;GET HASH KEY FOR LIST
TLZ A,-1
SKIPE VGCPRO
JRST LDQLS4
PUSH FXP,D
PUSH FXP,AR1
TLZ A,-1
SKIPE D,TT
JRST LDQLS3
PUSH P,A
PUSHJ P,SXHSH0
POP P,A
LDQLS3: SKIPN V.PURE ;SKIP FOR PURE HACKERY
JRST LDQLS1
PUSH FXP,D ;SAVE HASH KEY
PUSH P,A ;SAVE LIST
MOVNI T,1 ;THIS MEANS JUST LOOKUP
PUSHJ P,LDGPRO
POP P,B
POP FXP,D
JUMPN A,LDQLS2 ;ON GCPRO LIST, SO USE IT
MOVE A,B
PUSHJ P,PURCOPY ;NOT ON GCPRO LIST, SO PURCOPY IT
LDQLS1: MOVEI T,1 ;THIS MEANS PROTECT OR HAND BACK COPY
PUSHJ P,LDGPRO ;PROTECT LIST FROM FEROCIOUS GC!
LDQLS2: POP FXP,AR1
POP FXP,D
LDQLS5: JUMPE D,LDEVL7 ;MAYBE THIS LIST GOES INTO ATOMTABLE
HRRM A,(R) ;SAVE ADDRESS OF LIST (WHICH MAY
JRST LDABS1 ; BE DIFFERENT NOW) BACK INTO WORD
LDQLS4: JSP T,LDQLPRO
JRST LDQLS5
LDQLPRO:
HRRZ B,LDEVPRO ;GC-PROTECT HAPPENS BY PUSHING ONTO A LIST
PUSHJ P,CONS
MOVEM A,LDEVPRO
JRST %CAR
LDGPRO: SKIPE GCPSAR ;PROTECT SOMETHING ON THE GCPSAR
JRST .GCPRO
PUSHJ P,.GCPRO ;THE LOOKUP CAUSES THE CREATION OF A NEW ARRAY
JRST LDRSPT ;SO WE HAVE TO RESTORE PTRS AFTERWARDS
SUBTTL PURIFIABLE CALL
LDPRC: MOVE D,@LDAPTR ;[PURIFIABLE CALL]
TRNN D,-1 ;MUST HAVE NON-NIL ATOM TO CALL
JSP D,LDFERR
TLNE D,777000
JRST LDPRC1 ;JUMP IF ATOM HAS SPECIAL CELL
TLNE D,6
JSP D,LDFERR ;LOSE IF NUMBER
TLO D,1 ;ELSE TURN ON REFERENCE BIT
MOVEM D,@LDAPTR
HLRZ T,(D) ;FETCH SY2 DATA
HLL T,(T)
TLO T,SY.CCN ;ONLY CCN, NOT OTC!!
TLNN T,SY.PUR ;ONLY IF IMPURE
HLLM T,(T)
LDPRC1: HRR TT,D ;PUT ADDRESS OF ATOM IN CALL
SKIPGE T,LDPRLS(P) ;SKIP FOR PURIFYING HACKERY
JRST LDABS ;OTHERWISE WE'RE DONE
TLNN T,200000 ;SKIP FOR XCT STUFF
SETZ T, ;ELSE DO ORDINARY SMASH
PUSHJ P,PRCHAK ;*** SMASH! ***
JRST LDABS1
MOVEI A,(R) ;NOT SMASHED - CONS ONTO PURE LIST
MOVE B,LDPRLS(P)
PUSHJ P,CONS
MOVEM A,LDPRLS(P)
JRST LDABS1
;;; ROUTINE TO CLOBBER A CALL INTO BPS, POSSIBLY DOING XCT HACK.
;;; SKIPS ON *** FAILURE *** TO CLOBBER.
;;; T NON-ZERO => TRY XCT HACK; OTHERWISE ORDINARY SMASH.
;;; TT HAS UUO INSTRUCTION TO HACK.
;;; R HAS ADDRESS TO PUT UUO INTO.
;;; MUST PRESERVE AR1, R, F.
IFN D10,[
;VERSION FOR D10 ONLY, NEWER VERSION SUPPORTS EXTENDABLE NUMBER OF SEGMENTS
PRCHAK: JUMPE T,LDPRC5 ;T ZERO => ORDINARY SMASH
MOVE T,TT ;SAVE CALL IN T
IDIV TT,LDXSM1 ;COMPUTE HASH CODE FOR CALL
MOVNM D,LDTEMP ;SAVE NEGATIVE THEREOF
HLRZ TT,LDXBLT
ADD D,TT ;ADDRESS TO BEGIN SEARCH
CAMN T,(D) ;WE MAY WIN IMMEDIATELY
JRST LDPRC7
SKIPN (D)
JRST LDPRC6
ADD TT,LDXSM1 ;ELSE MAKE UP AN AOBJN POINTER
SUBI TT,-1(D) ; AND SEARCH FOR MATCHING CALL
MOVNI TT,(TT)
HRL D,TT
LDPRC2: CAMN T,(D)
JRST LDPRC7 ;FOUND MATCHING CALL
SKIPN (D)
JRST LDPRC6 ;FOUND EMPTY SLOT
AOBJN D,LDPRC2
HRLZ D,LDTEMP ;WRAPPED OFF THE END OF THE XCT AREA
HLR D,LDXBLT ; - MAKE UP NEW AOBJN POINTER
LDPRC3: CAMN T,(D) ;SECOND COPY OF THE LOOP
JRST LDPRC7 ;FOUND MATCHING CALL
SKIPN (D)
JRST LDPRC6 ;FOUND EMPTY SLOT
AOBJN D,LDPRC3
LDPRC4: MOVE TT,T ;TOTAL LOSS - MUST DO SMASH
LDPRC5: HRRZ AR2A,R ;PUT ADDRESS OF CALL IN AR2A
MOVEM TT,(AR2A) ;PUT CALL IN THAT PLACE
JRST LDSMSH ;NOW TRY TO SMASH IT, EXITING WITH SKIP ON FAILURE
LDPRC6: SKIPG LDXSIZ ;FOUND EMPTY SLOT
JRST LDPRC4 ;CAN'T USE IT IF PAGES PURIFIED
MOVEM T,(D) ;SAVE CALL INTO XCT AREA 2
MOVEM T,@LDXDIF ;ALSO SAVE INTO AREA 1
LDPRC7: ADD D,LDXDIF ;MAKE UP AN XCT TO POINT TO
HRLI D,(XCT) ; CALL IN AREA 1
MOVEM D,(R)
POPJ P,
] ;END IFN D10
IFN ITS+D20,[
;NEW STYLE SEARCH FOR PROPER LINK LOCATION; ADDS A NEW UUOLINKS SEGMENT IF
; OUT OF SPACE OR IF PARTIALLY EMPTY UUOLINK SEGMENT HAS BEEN PURIFIED
PRCHAK: JUMPN T,PRCHA1 ;DON'T SMASH IMMEDIATLY IF T NON-ZERO
PRCSMS: HRRZ AR2A,R ;PUT ADDRESS OF CALL IN AR2A
MOVEM TT,(AR2A) ;PUT CALL IN THAT PLACE
JRST LDSMSH ;TRY TO SMASH IT, EXITING WITH SKIP ON FAILURE
PRCHA1: PUSH FXP,R ;NEED D/R PAIR OF ACS
MOVE D,TT ;GET COPY OF THE CALL
IDIVI D,LDHSH1 ;COMPUTE FIRST HASH VALUE
MOVEM R,LDXHS1
MOVE D,TT ;THEN THE SECOND HASH VALUE
IDIVI D,LDHSH2
AOS R ;IT BEING ZERO COULD BE A DISASTER
MOVEM R,LDXHS2
SKIPN T,LDXPNT ;GET POINTER
JRST PRCH2A ;FIRST TIME THROUGH ALWAYS ADD NEW SEGMENT
PRCH1A: HRRZ D,LDXPSP(T) ;GET POINTER TO PURE PAGE
MOVEI R,LDXOFS(D) ;POINTER TO FIRST WORD OF DATA
ADDI D,SEGSIZ-1 ;THIS IS THE LAST WORD IN THE SEGMENT
ADD R,LDXHS1 ;START FROM THE FIRST HASH VALUE
PRCH1B: CAMN TT,(R) ;MATCH?
JRST PRCHA3 ;YUP, SO USE THIS SLOT
SKIPN (R) ;END OF CHAIN?
JRST PRCHA4 ;YES, ON TO NEXT SEGMENT
ADD R,LDXHS2 ;STEP BY HASH VALUE
CAILE R,(D) ;MUST NOT RUN OFF END OF SEGMENT
SUBI R,LDHSH1 ;SO TAKE IT MOD LDHSH1
JRST PRCH1B ;AND TRY THIS SLOT
PRCHA4: HLRZ D,LDXPSP(T) ;GET POINTER TO NEXT SEGMENT
JUMPE D,PRCHA2
MOVEI T,(D)
JRST PRCH1A
PRCHA3: HRRZ D,LDXPSP(T) ;SUBTRACTING THIS WILL GIVE ABSOLUTE SEG OFFSET
SUBM R,D
ADDI D,(T) ;THEN PRODUCE POINTER TO FROB TO XCT
POP FXP,R ;RESTORE POINTER TO CODE
HRLI D,(XCT)
MOVEM D,(R) ;THEN STORE THE NEW INSTRUCTION
POPJ P,
;GET HERE WITH C(R) POINTING TO SLOT TO ADD NEW ENTRY TO IN PURE TABLE, DUE TO
; THE DESIGN OF THE MECHANISM, IN THE CASES THAT R IS INVALID, A NEW UUO PAGE
; WILL HAVE TO BE ADDED AND R WILL NOT BE USED. IF THAT IS CHANGED, THIS
; ROUTINE MUST BE FIXED
PRCHA2: AOSLE LDXLPC ;IF THIS SEGMENT IS FULL
JRST PRCH2A ; ADD A NEW ONE
MOVEM TT,(R) ;STORE THE CALL IN THE POTENTIALLY PURE SEGMENT
HRRZ D,LDXPSP(T) ;THEN BUILD POINTER TO IMPURE SEGMENT
SUBM R,D
ADDI D,(T) ;D CONTAINS ADR IN IMPURE SEGMENT
MOVEM TT,(D) ;STORE THE CALL INSTRUCTION THERE
POP FXP,R ;GET ADR OF ACTUAL CODE
HRLI D,(XCT) ;THEN INSTRUCTION TO PLANT THERE
MOVEM D,(R)
POPJ P,
PRCH2A: PUSH FXP,TT ;SAVE TT OVER SEGMENT GRAB
PUSHJ P,LDXHAK ;ADD A NEW SEGMENT
LERR [SIXBIT \CANNOT ADD NEW UUOLINKS SEGMENT - FASLOAD!\]
POP FXP,TT
MOVE T,LDXLPL ;GET POINTER TO THE PAGE JUST ADDED
MOVEI D,LDXOFS(T) ;FIRST DATA ADR
ADD D,LDXHS1 ;ADR TO INSTALL CALL INTO
MOVEM TT,(D) ;STORE THE CALL TO BE POTENTIALLY SMASHED
HRLI D,(XCT) ;THE XCT INSTRUCTION
POP FXP,R
MOVEM D,(R) ;PLANT IN CODE
HRRZ D,LDXPSP(T) ;PURE SEGMENT POINTER
ADD D,LDXHS1
ADDI D,LDXOFS
MOVEM TT,(D) ;PLANT CALL IN POTENTIALLY PURE SEGMENT
POPJ P,
;HERE TO TRY TO SMASH CALL IN IMPURE SEGMENT. CALLED ONLY IF FLAG IS SET.
; POINTER TO WORD IN THE SEGMENT IS IN D. DESTROYS A, B, C, T
PRTRTS: HRRZ AR2A,D ;PUT ADDRESS OF CALL IN AR2A
PUSH FXP,D ;SAVE VALUABLE AC'S
PUSH FXP,TT
PUSH FXP,T
PUSHJ P,LDSMSH ;TRY TO SMASH THE CALL
JFCL ;WE DON'T REALLY CARE IF IT WINS OR NOT
POP FXP,T
POP FXP,TT
POP FXP,D
POPJ P,
] ;END IFN ITS+D10
;;; SMASH A CALL-TYPE UUO IN MEMORY TO BE A PUSHJ OR JRST OR WHATEVER.
;;; AR2A HAS THE LOCATION OF THE CALL.
;;; RETURN SKIPS IF IT CAN'T BE SMASHED.
;;; DESTROYS A, B, C, T, TT, D; SAVES AR1, AR2A, R, F.
;;; MUST NOT USER ANY PDL EXCEPT THE REGPDL (P).
.SEE PURIFY
LDSMSH: MOVE T,(AR2A)
LSH T,-33 ;T GETS THE CALL UUO OPCODE
CAIL T,CALL←-33
CAILE T,CALL←-33+NUUOCLS
POPJ P, ;RETURN IF NOT REALLY A CALL
HRRZ A,(AR2A)
MOVEI B,SBRL
PUSHJ P,GETLA ;TRY TO GET SUBR, FSUBR, OR LSUBR PROP
LDB D,[270400,,(AR2A)]
JUMPE A,LDSMNS ;JUMP IF NOT ANY OF THOSE
HLRZ B,(A)
HRRZ T,(AR2A)
HLRZ T,(T)
HLRZ T,1(T) ;GET ARGS PROPERTY FOR FUNCTION NAME
SOJL T,LDZA2 ;JUMP IF THERE ISN'T ANY
CAIG T,NACS ;ARGS PROPERTY IS SCREWY IF THIS SKIPS!
TLOA T,(CAIE D,) ;IF ARGS PROP OK, TEST FOR THAT EXACT NUMBER OF ARGS IN UUO
LDZA2: MOVE T,[CAILE D,NACS] ;IF NO OR BAD ARGS PROP, JUST CHECK FOR RANGE
CAIN B,QFSUBR
MOVE T,[CAIE D,17]
CAIN B,QLSUBR
MOVE T,[CAIE D,16]
XCT T ;AC FIELD OF CALL IS 0-5 FOR SUBRS, 16 LSUBR, 17 FSUBR
JRST POPJ1 ;SKIP RETURN IF CALL DOESN'T MATCH FUNCTION TYPE OR # ARGS
HRRZ A,(A) ;ELSE WIN - SMASH THE CALL
HLRZ A,(A) ;SUBR ADDRESS NOW IN A
SKIPA TT,(AR2A)
LDZAOK: HRLI A,(@) .SEE ASAR
MOVSI T,(PUSHJ P,) ;CALL BECOMES PUSHJ
TLNE TT,20000
ADDI A,1 ;HACK NCALLS CORRECTLY - ENTER AT ROUTINE+1
TLNE TT,1000
MOVSI T,(JRST) ;JCALL BECOMES JRST
LDZA1: IOR T,A
MOVEM T,(AR2A) ;***SMASH!***
POPJ P,
LDSMNS: HRRZ A,(AR2A) ;TRY TO GET ARRAY PROPERTY
MOVEI B,QARRAY
PUSHJ P,GET
MOVEI T,(A)
LSH T,-SEGLOG
MOVE T,ST(T)
TLNN T,SA
JRST POPJ1 ;LOSE IF NOT SAR
LDB T,[TTSDIM,,TTSAR(A)]
CAIE T,(D) ;MUST HAVE CORRECT NUMBER OF ARGS
JRST POP1J
MOVSI T,TTS<CN>
IORM T,TTSAR(A) ;SET "COMPILED-CODE-NEEDS-ME" BIT IN SAR
MOVE TT,(AR2A)
TLNN TT,20000
JRST LDZAOK
MOVSI T,(ACALL) ;FOR AN NCALL-TYPE UUO, SMASH IT TO
TLNE TT,1000 ; BE A CROCKISH ACALL OR AJCALL
MOVSI T,(AJCALL)
JRST LDZA1
SUBTTL GETDDTSYM HACKERY
LDGET: CAMN TT,XC-1
JRST LDLHRL
MOVE D,TT ;[GET DDT SYMBOL PATCH]
TLNN D,200000 ;MAYBE THE ASSEMBLER LEFT US A VALUE?
JRST LDGET2
JSP T,LDGTWD ;FETCH IT THEN
SKIPE LDF2DP
JRST LDGET2 ;CAN'T USE IT IF VERSIONS DIFFER
LDGET1: TLNE D,400000 ;MAYBE NEGATE SYMBOL?
MOVNS TT
LDB D,[400200,,D] ;GET FIELD NUMBER
XCT LDXCT(D) ;HASH UP VALUE FOR FIELD
MOVE T,LDMASK(D) ;ADD INTO FIELD
ADD TT,-1(R) ; MASKED APPROPRIATELY
AND TT,T
ANDCAM T,-1(R)
IORM TT,-1(R)
JRST LDBIN
LDGET2: UNLOCKI ;UNLOCK INTERRUPTS
PUSH FXP,. ;RANDOM FXP SLOT
PUSH FXP,AR1 ;SAVE UP ACS
PUSH FXP,D
PUSH FXP,R
PUSH FXP,F
MOVEI R,0
TLZ D,740000
REPEAT LOG2LL5,[
CAML D,LAPFIV+<1←<LOG2LL5-.RPCNT-1>>(R)
ADDI R,1←<LOG2LL5-.RPCNT-1>
] ;END OF REPEAT LOG2LL5
CAME D,LAPFIV(R) ;IF DDTSYM REQUEST IS FOR A GLOBAL SYM
JRST LDGT5A ;THEN FIND IT IN THE LAPFIV TABLE, AND GET ITS
LSHC R,-2 ;GLOBALSYM INDEX FROM THE PERMUTATION TABLE
LSH F,-42
LDB TT,LDGET6(F)
MOVE TT,LSYMS(TT)
JRST LDGT5B
LDGT5A: MOVEI TT,R70
CAMN D,[SQUOZE 0,R70]
JRST LDGT5B
PUSHJ P,UNSQOZ ;CONVERT SQUOZE TO A LISP SYMBOL
MOVEI C,(A)
MOVEI B,QSYM ;TRY TO FIND SYM PROPERTY
PUSHJ P,GET
JUMPN A,LDGETJ ;WIN
IFN ITS,[
JSP T,SIDDTP ;MAYBE WE CAN GET VALUE FROM DDT?
JRST LDGETX
LDB T,[004000,,-2(FXP)]
.BREAK 12,[..RSYM,,T]
JUMPE T,LDGETX ;LOSE, LOSE, LOSE
] ;END OF IFN ITS
IFN D10,[
SKIPN .JBSYM"
JRST LDGETX
LDB D,[004000,,-2(FXP)]
LDGET4: MOVE TT,D
IDIVI D,50
JUMPE R,LDGET4
PUSHJ P,GETDD0
JRST LDGETX
] ;END OF IFN D10
LDGT5B: MOVEM TT,-4(FXP) ;WIN, WIN - USE RANDOM FXP SLOT
MOVEI A,-4(FXP) ; TO FAKE UP A FIXNUM
JRST LDGETJ
LDGETX: MOVEI A,(C)
PUSHJ P,NCONS
MOVEI B,QGETDDTSYM ;DO A FAIL-ACT
PUSHJ P,XCONS
PUSHJ P,LDGETQ
LDGETJ: POP FXP,F ;RESTORE ACS
POP FXP,R
POP FXP,D
POP FXP,AR1
PUSHJ P,LDLRSP ;LOCKI AND RESTORE ARRAY POINTERS
MOVE TT,(A)
PUSHJ P,TYPEP ;FIGURE OUT WHAT WE GOT BACK
POP FXP,-1(FXP) ;POP RANDOM SLOT (REMEMBER THE LOCKI!)
CAIN A,QFIXNUM
JRST LDGET1
LDGETV: CAIN A,QFLONUM ;USE A FLONUM IF WE GET ONE
JRST LDGET1
LDGETW: PUSHJ P,LDGDDT ;FOR ANYTHING ELSE TRY DDT AGAIN
MOVEM TT,LDDDTP(P)
JRST LDGET2
LDGET6: REPEAT 4,[<11←24.>+<<<3-.RPCNT>*11>←30.> LAP5P(R)
]
IFN ITS,[
LDGDDT: JSP T,SIDDTP
JRST ZPOPJ ;0 => TOP LEVEL, OR NOT INFERIOR TO DDT
.BREAK 12,[..RSTP,,TT] ;-1,,0 => INFERIOR TO DDT, BUT NO SYMBOL TABLE
SKIPN TT ;1,,0 => INFERIOR TO DDT WITH SYMBOL TABLE
TLOA TT,-1
MOVSI TT,1
POPJ P,
] ;END OF IFN ITS
IFN D20,[
LDGDDT==:ZPOPJ ;FOR NOW, NEVER A DDT
] ;END IFN D20
IFN D10,[
LDGDDT: SKIPE TT,.JBSYM"
MOVSI TT,1
POPJ P,
] ;END OF IFN D10
LDXCT: MOVSS TT ;INDEX FIELD
HRRZS TT ;ADDRESS FIELD
LSH TT,23. ;AC FIELD
JFCL ;OPCODE FIELD
LDMASK: -1 ;INDEX FIELD
0,,-1 ;ADDRESS FIELD
0 17, ;AC FIELD
-1 ;OPCODE FIELD
LDLHRL: HRLZ TT,LDOFST
ADDM TT,-1(R)
JRST LDBIN
SUBTTL ARRAY, GLOBALSYM, AND ATOMTABLE ENTRY STUFF
LDAREF: PUSH FXP,TT ;[ARRAY REFERENCE]
MOVE D,@LDAPTR
TLNN D,777001
TLO D,11
MOVEM D,@LDAPTR
TRNN D,-1
JRST LDARE1 ;SKIP IF HACKING 'NIL'
TLNE D,777000 ;IF NO VC THEN MUST HACK SYMBOL
JRST LDARE1
HLRZ T,(D)
HLL T,(T)
TLO T,SY.CCN\SY.OTC ;COMPILED CODE NEEDS, OTHER THAN CALL REF
TLNN T,SY.PUR ;CAN'T WRITE IF PURE
HLLM T,(T)
LDARE1: MOVEI A,(D)
PUSHJ P,TTSR+1 ;NCALL TO TTSR
HLL TT,(FXP)
SUB FXP,R70+1
JRST LDABS
LDGLB: SKIPL TT ;[GLOBALSYM PATCH]
SKIPA TT,LSYMS(TT) ;GET VALUE OF GLOBAL SYMBOL
MOVN TT,LSYMS(TT) ;OR MAYBE NEGATIVE THEREOF
ADD TT,-1(R) ;ADD TO ADDRESS FIELD OF
HRRM TT,-1(R) ; LAST WORD LOADED
JRST LDBIN
LDATM: LDB T,[410300,,TT] ;[ATOMTABLE ENTRY]
JRST LDATBL(T)
LDATBL: JRST LDATPN ;PNAME
JRST LDATFX ;FIXNUM
JRST LDATFL ;FLONUM
BG$ JRST LDATBN ;BIGNUM
BG% JRST LDATER
DB$ JRST LDATDB ;DOUBLE
DB% JRST LDATER
CX$ JRST LDATCX ;COMPLEX
CX% JRST LDATER
DX$ JRST LDATDX ;DUPLEX
DX% JRST LDATER
.VALUE ;UNDEFINED
LDATPN: MOVEI D,(TT) ;[ATOMTABLE PNAME ENTRY]
PUSH FXP,R
CAILE D,LPNBUF
JRST LDATP2
MOVEI C,PNBUF-1
LDATP1: JSP T,LDGTWD
ADDI C,1
MOVEM TT,(C)
SOJG D,LDATP1
SETOM LPNF
JRST LDATP4
LDATP2: PUSH FXP,D
LDATP3: JSP T,LDGTWD
JSP T,FWCONS
PUSH P,A
SOJG D,LDATP3
POP FXP,T
MOVNS T
PUSHJ FXP,LISTX
SETZM LPNF
LDATP4: PUSH FXP,AR1
PUSHJ P,RINTERN
POP FXP,AR1
POP FXP,R
LDATP8: MOVE TT,LDAAOB
MOVEM A,@LDAPTR
AOBJP TT,LDAEXT
MOVEM TT,LDAAOB
JRST LDBIN
LDATFX: JSP T,LDGTWD ;[ATOMTABLE FIXNUM ENTRY]
PUSH FXP,TT
MOVEI A,(FXP)
PUSH P,AR1
PUSHJ P,GCLOOK
POP P,AR1
POP FXP,TT
SKIPE A
LDATX0: TLOA A,10
JRST LDATX2
LDATX1: TLO A,2
JRST LDATP8
LDATX2: SKIPE V.PURE
JRST LDATX3
JSP T,FXCONS
JRST LDATX1
LDATX3: PUSHJ P,PFXCONS
JRST LDATX0
LDATFL: JSP T,LDGTWD ;[ATOMTABLE FLONUM ENTRY]
PUSH FLP,TT
MOVEI A,(FLP)
PUSH P,AR1
PUSHJ P,GCLOOK
POP P,AR1
POP FLP,TT
SKIPE A
LDATL0: TLOA A,10
JRST LDATL2
LDATL1: TLO A,4
JRST LDATP8
LDATL2: SKIPE V.PURE
JRST LDATL3
JSP T,FLCONS
JRST LDATL1
LDATL3: PUSHJ P,PFLCONS
JRST LDATL0
IFN BIGNUM,[
LDATBN: PUSH FXP,TT ;[ATOMTABLE BIGNUM ENTRY]
MOVEI D,(TT)
MOVEI B,NIL
LDATB1: JSP T,LDGTWD
SKIPE V.PURE
JRST LDATB2
JSP T,FWCONS
PUSHJ P,CONS
JRST LDATB3
LDATB2: PUSHJ P,PFXCONS
PUSHJ P,PCONS
LDATB3: MOVE B,A
SOJG D,LDATB1
POP FXP,TT
TLNE TT,1
TLO A,-1
SKIPE V.PURE
JRST LDATB6
PUSHJ P,BNCONS
JRST LDATB7
LDATB6: PUSHJ P,PBNCONS
TLO A,10
LDATB7: TLO A,6
JRST LDATP8
] ;END OF IFN BIGNUM
LDAEXT: MOVE T,TT ;[ATOMTABLE EXTEND]
HRLI T,-ILDAT
MOVEM T,LDAAOB
ADDI TT,ILDAT
ASH TT,1
UNLOCKI .SEE ERROR5 ;.REARRAY MAY PULL AN ERINT
PUSH FXP,AR1
PUSH FXP,R
PUSH FXP,F
PUSH P,[LDRFRF]
PUSH P,LDASAR
PUSH P,[TRUTH]
PUSH FXP,TT
MOVEI A,(FXP)
PUSH P,A
MOVNI T,3
JRST .REARRAY
LDRFRF: SUB FXP,R70+1 ;[RETURN FROM .REARRAY FUNCTION]
POP FXP,F
POP FXP,R
POP FXP,AR1
PUSHJ P,LDLRSP
JRST LDBIN
SUBTTL ENTRY POINT
LDENT: HRRZ C,@LDAPTR ;[ENTRY POINT INFO]
MOVSS TT
HRRZ A,@LDAPTR
PUSH P,A
PUSH P,C
SKIPN B,VFASLOAD
JRST LDNRDF
CAIN B,TRUTH ;IF C(FASLOAD) IS T
MOVEI B,SBRL ;THEN USE (SUBR LSUBR FSUBR)
HRRZ A,(P) ;IS PROPERTY BEING DEFINED ONE OF INTEREST?
PUSHJ P,MEMQ
JUMPE A,LDNRDF ;NOPE, SO PRINT NO MESSAGES
MOVE B,VFASLOAD
CAIN B,TRUTH ;IF C(FASLOAD) IS T
MOVEI B,SBRL ;THEN USE (SUBR LSUBR FSUBR)
HRRZ A,-1(P) ;ATOM THAT IS BEING HACKED
PUSHJ P,GETL ;DID THIS PREVIOUSLY HAVE A PROP OF INTEREST?
JUMPE A,LDNRDF ;NOPE, NO MESSAGES TO BE PRINTED
PUSH P,A
PUSH FXP,AR1
PUSH FXP,R
PUSH FXP,F
Q% PUSHJ P,IOGBND
Q$ MOVEI A,TRUTH
Q$ JSP T,SPECBIND
Q$ 0 A,V%TERPRI
STRT 17,[SIXBIT \↑M;CAUTION#! !\]
MOVE A,-2(P)
Q% PUSHJ P,PRIN1
Q$ PUSHJ P,MSGFCK
Q$ TLO AR1,200000
Q$ PUSHJ P,$PRIN1 ;SAVES AR1
HRRZ B,@(P)
HLRZ B,(B)
MOVEI TT,[SIXBIT \, A SYSTEM !\]
10% CAIL B,ENDFUN
10$ CAIGE B,BEGFUN
MOVEI TT,[SIXBIT \, A USER !\]
STRT 17,(TT)
HLRZ A,@(P)
Q% PUSHJ P,PRIN1
Q$ PUSHJ P,$PRIN1 ;AR1 IS STILL GOOD
HRRZ TT,@(P)
HLRZ TT,(TT)
MOVEI T,(TT)
LSH T,-SEGLOG
HRRZ T,ST(T)
CAIE T,QRANDOM
JRST LDENT4
STRT 17,[SIXBIT \ AT !\] ;USE OF PRINL4 HERE DEPENDS ON PRIN1
PUSHJ P,PRINL4 ; LEAVING ADDRESS OF TYO IN R (AND FILES IN AR1)
LDENT4: STRT 17,[SIXBIT \, IS BEING REDEFINED↑M; AS A !\]
HRRZ A,-1(P)
Q% PUSHJ P,PRIN1
Q$ PUSHJ P,$PRIN1
STRT 17,[SIXBIT \ BY FASL FILE !\]
MOVE A,LDFNAM
Q% PUSHJ P,PRIN1
Q$ PUSHJ P,$PRIN1
Q% PUSHJ P,TERPRI
Q$ PUSHJ P,TERP1
PUSHJ P,UNBIND
POP FXP,F
POP FXP,R
POP FXP,AR1
SUB P,R70+1
LDNRDF: MOVE B,(P)
MOVE A,-1(P)
PUSHJ P,REMPROP
POP P,C
MOVE A,(P)
JSP T,LDGTWD
PUSH FXP,TT
MOVEI B,@LDOFST
CAILE B,(R)
JSP D,LDFERR
PUSHJ P,PUTPROP
POP FXP,TT
HLRZ T,TT
HLRZ B,@(P)
HLRZ D,1(B)
CAIN D,(T) ;NEEDN'T DO IT IF ALREADY SAME
JRST LDPRG3
LDPARG: ;ELSE TRY TO CLOBBER IT IN
PURTRAP LDPRG9,B, HRLM T,1(B)
LDPRG3: SUB P,R70+1
JRST LDBIN
SUBTTL PUTDDTSYM FROM FASL FILE
;;; THE WORD IN TT HAS SQUOZE FOR DEFINED SYMBOL, PLUS FOUR BITS:
;;; 4.9 1 => FOLLOWING WORD IS VALUE, 0 => LOAD LOC IS VALUE
;;; 4.8 LH IS RELOCATABLE
;;; 4.7 RH IS RELOCATABLE
;;; 4.6 IS GLOBAL (0 => SYMBOLS = 'T LOADS, BUT = 'SYMBOLS DOES NOT)
IFN ITS,[
LDPUT: SKIPN A,V$SYMBOLS
JRST LDPUT3 ;FORGET IT IF SYMBOLS NOT NON-NIL
CAIE A,Q$SYMBOLS
JRST LDPUT7
TLNN TT,40000 ;IF HAS 'SYMBOLS, LOAD ONLY GLOBALS
JRST LDPUT3
LDPUT7: JUMPL TT,LDPUT2
MOVEI D,(R)
LDPUT0: TLZ TT,740000
TLO TT,%SYGBL
SKIPG A,LDDDTP(P)
JRST LDBIN ;FORGET IT IF DDT HAS NO SYMBOL TABLE
MOVE T,TT
TRNE A,-1 ;MAY HAVE TO CREATE SYMBOL TABLE ARRAY
JRST LDPUT5
UNLOCKI
PUSH FXP,AR1
PUSHJ P,SAVX5
MOVEI TT,LLDSTB*2+1
MOVSI A,-1
PUSHJ P,MKFXAR
PUSHJ P,RSTX5
POP FXP,AR1
PUSHJ P,LDLRSP
HRRM A,LDDDTP(P)
LDPUT4: MOVSI TT,-LLDSTB ;USE TT FOR TWO THINGS HERE!
MOVEM TT,@TTSAR(A)
LDPUT5: SETZ TT,
AOS TT,@TTSAR(A) ;GET AOBJN POINTER
JUMPGE TT,LDPUT4
MOVEM T,@TTSAR(A) ;SAVE SQUOZE FOR SYMBOL
ADD TT,R70+1
MOVEM D,@TTSAR(A) ;SAVE ITS VALUE
MOVE T,TT
SETZ TT,
MOVEM T,@TTSAR(A) ;SAVE BACK INCREMENTED AOBJN PTR
JUMPL T,LDBIN
PUSHJ P,LDPUTM ;MAY BE TIME TO OUTPUT BUFFER
JRST LDBIN
LDPUTM: SETZ TT,
MOVN T,@TTSAR(A)
MOVSI T,(T)
HRR T,TTSAR(A)
AOSGE T
.BREAK 12,[..SSTB,,T]
POPJ P,
] ;END OF IFN ITS
IFN D10,[
LDPUT: SKIPN A,V$SYMBOLS
JRST LDPUT3
CAIE A,Q$SYMBOLS
JRST LDPUT7
TLNN TT,40000
JRST LDPUT3
LDPUT7: SKIPN .JBSYM"
JRST LDPUT3
PUSH FXP,AR1
JUMPL TT,LDPUT2
MOVE D,R
LDPUT0: PUSH FXP,D
PUSH FXP,F
TLZ TT,740000
LDPUT1: MOVE T,TT
IDIVI TT,50
JUMPE D,LDPUT1
MOVEI B,-1(FXP)
MOVSI R,400000
PUSHJ P,PUTDD0
POP FXP,F
SUB FXP,R70+1
POP FXP,R
POP FXP,AR1
JRST LDBIN
] ;END OF IFN D10
LDPUT2: MOVE D,TT
JSP T,LDGTWD
EXCH TT,D
TLNN TT,100000
JRST LDPT2A
MOVE T,LDOFST
ADD T,D
HRRM T,D
LDPT2A: TLNN TT,200000
JRST LDPT2B
HRLZ T,LDOFST
ADD D,T
LDPT2B: TLZ T,740000
TLO T,%SYGBL+%SYHKL ;GLOBAL AND HALF-KILLED
JRST LDPUT0
20$ WARN [WHAT TO DO ABOUT TOPS-20 LDPUT]
20$ LDPUT:
LDPUT3: JUMPGE TT,LDBIN ;DON'T WANT TO PUT DDT SYM, BUT
JSP T,LDGTWD ; MAYBE NEED TO FLUSH EXTRA WORD
JRST LDBIN
LDLOC: MOVEI TT,@LDOFST
MOVEI D,(R)
CAMLE D,LDHLOC
MOVEM D,LDHLOC
CAMG TT,LDHLOC
JRST LDLOC5
MOVE D,LDHLOC
SUBI D,(R)
MOVSI D,(D)
ADD R,D
HRR R,LDHLOC
SETZ TT,
SUB F,R70+1 ;BEWARE THIS BACK-UP CROCK!
ADD AR1,[040000,,]
JRST LDABS
LDLOC5: HRRZ D,LDOFST
CAIGE TT,(D)
JSP D,LDFERR
MOVEI D,(TT)
SUBI D,(R)
MOVSI D,(D)
ADD R,D
HRRI R,(TT)
JRST LDBIN
SUBTTL EVALUATE MUNGEABLE
LDEVAL: SETZ D, ;[EVALUATE MUNGEABLE]
PUSHJ P,LDLIST ;IF D IS LEFT 0 AFTER LDLIST, THEN WANT ENTRY INTO ATOMTABLE
MOVEI B,(P) ;B HAS ADDR OF FASLOAD TEMPS ON STACK
PUSH P,A
PUSHJ P,LDEV0
SUB P,R70+1
JUMPN D,LDBIN
JSP T,LDQLPRO ;PUSHES GOODY ONTO THE LDEVPRO LIST
LDEVL7: TLO A,16 ;AND GOES OFF TO ENTER INTO THE ATOMTABLE
JRST LDATP8
LDEV0: UNLOCKI ;EVALUATES AN S-EXPRESSION IN A
IFN QIO,[
JUMPE D,LDEV2 ;IN QIO, ALLOWS FOR RECURSIVE FASLOADING
SETZM FASLP ;EXCEPT WHEN EVALUATING FOR ENTRY INTO ATOMTABLE
PUSH P,A
MOVE C,LDPRLS(B)
TLNN C,600000
HRRZM C,VPURCLOBRL
IFN D10,[
TLNN C,100000
JRST LDEV4
HRRZM R,HBPORG
JRST LDEV5
LDEV4:
] ;END OF IFN D10
MOVEI TT,(R)
JSP T,FXCONS
MOVEM A,VBPORG
LDEV5: HRRZ TT,LDOFST ;IN CASE EVALUATION CHANGES BPORG,
SUBI TT,(R) ; MUST CHANGE LDOFST TO BE AN
HRRM TT,LDOFST ; ABSOLUTE QUANTITY
MOVNI T,LFTMPS
PUSH FXP,BFTMPS+LFTMPS(T)
AOJL T,.-1
POP P,A
LDEV2:
] ;END OF IFN QIO
PUSH FXP,B
PUSH FXP,AR1
PUSH FXP,D
PUSH FXP,R
PUSH FXP,F
PUSHJ P,EVAL
POP FXP,F
POP FXP,R
POP FXP,D
POP FXP,AR1
POP FXP,B
IFN QIO,[
JUMPE D,LDEV1
10$ MOVE C,LDPRLS(B)
10$ TLNE C,100000
10$ SKIPA R,HBPORG
MOVE R,@VBPORG
HRRZ T,LDBGEN(B)
MOVEM T,FASLP
MOVEI T,LFTMPS-1
POP FXP,BFTMPS(T)
SOJGE T,.-1
HRRZ TT,LDOFST ;NOW RE-RELOCATE THE LOAD OFFSET
ADDI TT,(R)
HRRM TT,LDOFST
HRRZ T,VPURCLOBRL
HRRM T,LDPRLS(B)
] ;END OF IFN QIO
LDEV1: PUSH P,A
10$ MOVE TT,LDPRLS(B) ;FOR D10, PASS LDPRLS IN TT TO LDGTSP
PUSHJ P,LDGTSP
POP P,A
JRST LDLRSP ;GET SPACE, LOCKI, AND RESTORE PTRS
SUBTTL END OF FASLOAD FILE
LDBEND: TRZ TT,1 ;CROCK!
CAME TT,[SIXBIT \*FASL*\]
JSP D,LDFERR
MOVEI TT,LDFEND
MOVEM TT,LDEOFJ
IFN ITS,[
SKIPLE A,LDDDTP(P)
TRNN A,-1
CAIA
PUSHJ P,LDPUTM ;MAYBE HAVE TO FORCE LDPUT'S BUFFER
] ;END OF IFN ITS
HLLZS LDDDTP(P) ;WILL USE FOR SWITCH LATER
JSP T,LDGTWD
TRZ TT,1 ;COMPATIBILITY CROCK
CAME TT,[SIXBIT \*FASL*\]
JRST LDBEN1
HLLOS LDDDTP(P)
MOVEM F,LDTEMP
JRST LDFEND
LDBEN1: TRZ TT,1
CAME TT,[14060301406]
10% JSP D,LDFERR
10$ JUMPN TT,LDFERR
LDFEND: TLZ R,-1 ;END OF FILE
CAMGE R,LDHLOC
MOVE R,LDHLOC
HRRZS TT,R
IFN D10,[
MOVE C,LDPRLS(P)
TLNN C,100000
JRST LDFEN2
HRRZM R,HBPORG
JRST LDFEN3
LDFEN2: JSP T,FXCONS
MOVEM A,VBPORG
LDFEN3:
] ;END OF IFN D10
IFN ITS+D20,[
JSP T,FXCONS
MOVE D,(A)
EXCH A,VBPORG
MOVE TT,(A)
SKIPL LDPRLS(P)
JRST LDZPUR
HLLOS NOQUIT
ANDI TT,PAGMSK
ANDI D,PAGMSK
LSHC TT,-PAGLOG
SUBI D,(TT)
ROT TT,-4
ADDI TT,(TT)
ROT TT,-1
TLC TT,770000
ADD TT,[450200,,PURTBL]
MOVEI T,1
LDNPUR: TLNN TT,730000
TLZ TT,770000
IDPB T,TT
SOJGE D,LDNPUR
PUSHJ P,CZECHI
LDZPUR:
] ;END OF IFN ITS+D20
;FALLS THROUGH
;FALLS IN
PUSH FXP,F ;SAVE POINTER TO I/O BUFFER
HRRZ F,LDAAOB
LDGCPR: SOJLE F,LDSDPL ;[GC PROTECT AS YET UNPROTECTED ATOMS]
SKIPE INTFLG
PUSHJ P,LDTRYI
MOVEI TT,(F)
MOVE AR2A,@LDAPTR
HRRZ A,AR2A
JUMPE A,LDGCPR ;LOSING MIDAS!
TLNE AR2A,777000 ;WAS VALUE CELL CREATED BY FASLOAD?
JRST LDGCPR ;YES, THEN NO NEED TO HACK IT AT ALL
TLNN AR2A,6
JRST LDGCPR ;NOT NUMBER, HACKED ALREADY
TLNN AR2A,10
TLNN AR2A,1
JRST LDGCPR
LDGCP1: HRRZ A,AR2A
CAIGE A,IN0+XHINUM
CAIGE A,IN0-XLONUM
CAIA
JRST LDGCPR
;IF FOR SOME REASON, THIS CAUSES THE CREATION OF THE GCPSAR
; I STILL DONT THINK WE NEED TO RESTORE PTRS HERE.
;I DISAGREE, SO I'M STICKING IN A CALL TO LDRSPT - GLS
PUSHJ P,%GCPRO
PUSHJ P,LDRSPT
JRST LDGCPR
SUBTTL SMASH DOWN PURE LIST
LDSDPL: SKIPL TT,LDPRLS(P) ;[SMASH DOWN PURE LIST]
TLNE TT,200000
JRST LDEOMM
MOVEM TT,VPURCLOBRL
MOVEI F,VPURCLOBRL
LDSDP1: SKIPN TT,LDPRLS(P)
JRST LDEOMM
SKIPN INTFLG
JRST LDSDP2
SKIPE INTFLG
PUSHJ P,LDTRYI
LDSDP2: HRRZ T,(TT)
MOVEM T,LDPRLS(P)
HLRZ AR2A,(TT)
PUSHJ P,LDSMSH
JRST LDSDP3
HRRZ F,(F)
JRST LDSDP1
LDSDP3: MOVE TT,LDPRLS(P)
HRRM TT,(F)
JRST LDSDP1
SUBTTL END OF FASLOAD, AND RANDOM ROUTINES
LDEOMM: POP FXP,LDTEMP ;GET POINTER TO I/O BUFFER
MOVE TT,LDDDTP(P)
Q$ MOVE A,LDBGEN(P)
10$ MOVE C,LDPRLS(P)
POPI P,LDNPDS ;[END OF MOBY MESS!!!]
TRNE TT,-1
JRST LDEOM1
Q$ PUSHJ P,$CLOSE ;CLOSE FILE ARRAY
Q% 10% .CLOSE DSIC,
Q% 10$ RELEASE DSIC,
SETZM LDBSAR
MOVE A,VBPORG
10$ MOVE TT,HBPORG
10$ TLNE C,100000
10$ JSP T,FXCONS
UNLOCKI
PUSHJ P,UNBIND
HRRZ TT,-2(P) ;FOR DEBUGGING PURPOSES,
HRRZ D,-1(P) ; MAKE SURE PDLS ARE OKAY
HRRZ R,(P)
SUB P,R70+3
JRST PDLCHK
LDEOM1: UNLOCKI
Q$ PUSH P,A ;PUT LDBSAR BACK ON PDL
JRST LDDISM
LDTRYI: UNLOCKI ;[TRY AN INTERRUPT]
LDLRSP: LOCKI ;[LOCKI AND RESTORE POINTERS]
LDRSPT: HRRZ TT,LDASAR ;[RESTORE ARRAY POINTERS]
HRRZ TT,TTSAR(TT)
HRRM TT,LDAPTR
HRRZ TT,LDBSAR
IFE QIO*D10,[
HRRZ TT,TTSAR(TT)
HRRM TT,LDBPTR
] ;END IFE QIO*D10
.ELSE HLLZS LDBPTR
POPJ P,
LDLIST: MOVEI C,-1(P) .SEE LDOWL
JRST LDLIS1
LDLIS0: JSP T,LDGTWD
LDLIS1: LDB T,[410300,,TT] ;[CONSTRUCT LIST]
JRST LDLTBL(T)
LDLTBL: JRST LDLATM ;ATOM
JRST LDLLST ;LIST
JRST LDLDLS ;DOTTED LIST
JRST LDOWL ;EVALUATE TOP FROB ON STACK
IFN HNKLOG, JRST LDLHNK ;HUNK
.ELSE JRST FASHNE
REPEAT 2, .VALUE
JRST LDLEND ;END OF LIST
LDLATM: MOVE A,@LDAPTR ;FOR ATOM, MAYBE SET USAGE BIT,
TLNN A,777011 ; THEN SHOVE ON STACK
IOR A,D
MOVEM A,@LDAPTR
PUSH P,A
TRNN A,-1
JRST LDLIS0 ;SKIP SY2 CHECK IF SYMBOL 'NIL'
TLNN A,777006 ;IF HAS VALUE CELL, OR IS NUMBER, DON'T DO SY2
TLNN D,1 ;IF SETTING USAGE BIT THEN ALSO DO SO IN SY2
JRST LDLIS0
HLRZ T,(A) ;GET SY2 WORD
HLL T,(T)
TLO T,SY.CCN\SY.OTC ;MUST FLAG ATOM AS NEEDED
TLNN T,SY.PUR ;SET MEMORY UNLESS PURIFIED
HLLM T,(T)
JRST LDLIS0
LDLLST: TDZA A,A ;FOR LIST, USE NIL AS END
LDLDLS: POP P,A ;FOR DOTTED LIST, USE TOP ITEM
HRRZS TT
JUMPE TT,LDLLS3
LDLLS1: POP P,B ;NOW POP N THINGS AND CONS THEM UP
PUSHJ P,XCONS
SOJG TT,LDLLS1
LDLLS3: PUSH P,A
SKIPE INTFLG
PUSHJ P,LDTRYI
JRST LDLIS0
LDOWL: MOVE A,(P)
MOVEI B,(C) ;B HAS ADDR OF FASLOAD TEMPS ON STACK
PUSH P,C
PUSHJ P,LDEV0
POP P,C
MOVEM A,(P)
JRST LDLIS0
IFN HNKLOG,[
LDLHNK: MOVEI T,-1(TT)
JSP AR2A,HUNKF0 ;SAVES C
PUSH P,A
JRST LDLIS0
] ;END OF IFN HNKLOG
LDLEND: HLRZ D,TT
TRC D,777776
TRNE D,777776
JSP D,LDFERR
POP P,A
MOVSS TT
HRRI TT,(A)
POPJ P,
;;; SECOND FILE NAME OF THIS LISP WHEN ASSEMBLED (VERSION NUMBER
;;; THIS LOCATION IS REFERENCED BY FASLAP WHEN CREATING A BINARY
;;; FILE. IT CONTAINS THE VALUE OF .FNAM2 PLUS EXTRA BITS
;;; TO DISTINGUISH SOME CONDITIONAL ASSEMBLY FLAGS.
;;; THE CONTENTS OF THIS LOCATION ARE PRIMARILY USED TO DETERMINE
;;; WHETHER FASLOAD MAY USE VALUES OF DDT SYMBOLS SUPPLIED BY
;;; FASLAP; IT DOES SO ONLY IF FASLAP'S VERSION NUMBER, AS
;;; DETERMINED BY THIS LOCATION, IS THE SAME AS FASLOAD'S.
ZZ==-1
ZZZ==0
;;; BIBOP USED TO BE THE 3RD NUMBER HERE
IRP X,,[D10,ML,1,BIGNUM,MOBIOF]
ZZ==ZZ←1
ZZZ==<ZZZ←1>\X
TERMIN
LDFNM2: <.FNAM2&ZZ>\ZZZ
EXPUNGE ZZ ZZZ
IFE QIO,[
LDFNSET: MOVE A,LDFNAM
JSP T,LNG1A ;GETS LENGTH OF ARG
MOVE A,LDFNAM
CAIN TT,4
POPJ P,
CAIGE TT,2
JRST SCRFUN ;COMPUTES STANDARD FILE SPECIFICATION LIST
JSP T,%CADR ;FROM INPUT ARG
MOVE B,IUNIT
PUSHJ P,CONS
HLRZ B,@LDFNAM
JRST XCONS
] ;END OF IFE QIO
IFE QIO,[
LDGTW0: HRLZI F,-LLDBF ;RESET THE POINTER AND THIS TIME GET A REAL DATA WORD
LDGTWD: MOVE TT,@LDBPTR ;PICK UP WORD FROM INPUT BUFFER
AOBJN F,(T) ;RETURN WITH WORD
LDGTW1: MOVE F,@LDBSAR .SEE ASAR
MOVE F,-1(F) ;THAT WAS NO DATA WORD - MUST GET MORE
IFN ITS,[
ADD F,[1,,]
MOVE TT,F
.IOT DSIC,F
TLNN F,-1 ;SKIP IF WE DIDNT GET A WHOLE BUFFERFUL
JRST LDGTW0
CAMN F,TT ;SKIP IF WE GOT AT LEAST ONE WORD
JSP D,@LDEOFJ ;OTHERWISE GO CRY A LOT, OR SOMETHING
HLRES F ;CALCULATE POINTER FOR THE PARTIAL BLOCK
ADDI F,LLDBF
MOVNS F
HRLZS F
JRST LDGTWD ;NOW GO GET A REAL DATA WORD
] ;END OF IFN ITS
IFN D10,[
ADDI F,-1 ;SIMULTANEOUS +1 IN LH -1 IN RH
MOVEM F,D10ARD ;SAVE IN I/O LIST
IFN SAIL,[
PUSH FXP,D
PUSH FXP,R
HRRZ D,D10ARD
AOJ D, ;D10ARD POINTS TO ADDRESS BEFORE
HRLI D,-1(D)
AOBJN D,.+1 ;CONS UP BLT PTR
SETZM -1(D) ;ZERO FIRST WORD
MOVEI R,LLDBF-2(D) ;CALCULATE END-WORD ADDR
BLT D,(R) ;BLLLLLLLLLLLLLLLLLLLL. . .LLLLLT
POP FXP,R
POP FXP,D
] ;END OF IFN SAIL
IN DSIC,D10ARD
JRST LDGTW0
AOSN LDEOFP ;GETTING EOF FLAG ONCE IS OKAY
JRST LDGTW0
JSP D,@LDEOFJ ;TWICE IS A LOSER
] ;END OF IFN D10
] ;END OF IFE QIO
IFN QIO,[
IFN ITS,[
LDGTW0: SUB F,FB.BFL(TT)
HRLZI F,(F)
HRRI F,FB.BUF
LDGTWD: MOVE TT,@LDBPTR
AOBJN F,(T)
LDGTW1: HRRZ TT,LDBSAR
HRRZ TT,TTSAR(TT)
PUSH FXP,FB.IBP(TT)
MOVE F,FB.BFL(TT)
SUBI F,1
.CALL LDGTW9
.LOSE 1400
POPI FXP,1
ADDI F,1
CAME F,FB.BFL(TT)
SOJA F,LDGTW0
JSP D,@LDEOFJ
LDGTW9: SETZ
SIXBIT \SIOT\ ;"STRING" I/O TRANSFER
,,F.CHAN(TT) ;CHANNEL #
,,0(FXP) ;BYTE POINTER
400000,,F ;BYTE COUNT
];END IFN ITS
IFN D20,[
LDGTW0: SUB F,FB.BFL(TT) ;MAKE F INTO AOBJN POINTER
HRLZI F,(F)
HRRI F,FB.BUF ;POINTING INTO THE BUFFER
LDGTWD: AOBJP F,LDGTW1
SUBI F,1 ;READJUST TO ACCESS CORRECT WORD
MOVE TT,@LDBPTR
AOJA F,(T) ;FIXUP AOBJN POINTER THEN RETURN
LDGTW1: HRRZ TT,LDBSAR
HRRZ TT,TTSAR(TT)
PUSHJ FXP,SAV3 ;SAVE ACS WHICH WILL BE DESTROYED
HRRZ 1,F.JFN(TT) ;JFN INTO AC 1
MOVE 2,FB.IBP(TT) ;BYTE POINTER INTO AC 2
MOVN 3,FB.BFL(TT) ;READ THIS MANY BYTES
SIN ;DO THE INPUT
ERJMP LDGTWE ;WE CAN IGNORE ERROR IF IT IS EOF
LDGTE1: MOVN F,3 ;GET POSITIVE NUMBER OF BYTES LEFT UNREAD
PUSHJ FXP,RST3 ;RESTORE SAVED ACS
CAME F,FB.BFL(TT) ;DID WE READ ANYTHING?
SOJA F,LDGTW0 ;YES, SO EMPTY THE BUFFER BEFORE GIVING EOF
JSP D,@LDEOFJ
LDGTWE: MOVEI 1,.FHSLF ;GET OUR LAST ERROR
GETER
HRRZS 2 ;ONLY WANT ERROR CODE
CAIN 2,IOX4 ;EOF?
JRST LDGTE1
MOVEI 1,.PRIOU ;OUTPUT ERROR TO PRIMARY OUTPUT CHANNEL
HRLOI 2,.FHSLF ;LAST ERROR FOR OUR PROCESS
SETZ 3, ;NO LIMIT TO AMOUNT OF OUTPUT
ERSTR
.LOSE ;FAILED
.LOSE ;FAILED
PUSHJ FXP,RST3 ;RESTORE SAVED AC'S
JSP D,@LDEOFJ ;MAKE BELIEVE WE HIT EOF
] ;END IFN D20
IFN D10,[
LDGTW0: POP P,T
MOVE TT,FB.HED(TT) ;GET BUFFER HEADER ADDRESS
MOVN F,2(TT) ;NUMBER OF WORDS IN BUFFER
HRLZI F,-1(F)
ADDI F,1 ;NOW THE ACTUAL FIRST WORD
LDGTWD: MOVE TT,LDBSAR ;GET POINTER TO SAR
HRRZ TT,TTSAR(TT)
MOVE TT,FB.HED(TT) ;GET POINTER TO BUFFER HEADER
HRRZ TT,1(TT) ;GET FIRST WORD OF BUFFER - 1
HRLI TT,F ;INDEXED OFF OF F
MOVE TT,@TT
AOBJN F,(T)
LDGTW1: HRRZ TT,LDBSAR
HRRZ TT,TTSAR(TT)
PUSH P,T
HRLZ T,F.CHAN(TT) ;WE MUST BUILD INSTRUCTION
LSH T,5 ;CHANNEL IN AC FIELD
TLO T,(IN) ;NOW MAKE IT AN INSTRUCTION
XCT T ;GET AS MANY WORDS AS POSSIBLE
JRST LDGTW0 ;IF SUCCESS THEN SETUP NEW POINTERS
POP P,T
JSP D,@LDEOFJ
] ;END IFN D10
] ;END OF IFN QIO
PGTOP FSL,[FASLOAD]